From 7351f83d336d9edadc5d2a8d4df7f928c61fa643 Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Mon, 10 Aug 2026 15:52:22 +1000 Subject: [PATCH 01/13] Key the temperature cache on everything it reads (#41) Binding the temperature-response parameters made them writable but not effective. The cache was keyed on (leaf_temp_, atm_o2_kpa_) alone, justified by "same inputs -> bit-identical outputs" -- true while those parameters were unreachable C++ members, false once they were bound. Silent: setting rd_to_vcmax_ratio_ on a solved leaf and re-supplying the same drivers left R_d at 1.44 where a fresh leaf gave 2.88, with assimilation unchanged to every digit. The key now covers every scalar the block reads, which also closes the silent half of hazard 10 for vcmax_25/jmax_25. Golden bit-identical; 2.99 vs 3.00 us/solve interleaved x3. Co-Authored-By: Claude Fable 5 --- NEWS.md | 39 ++++++++++++++ inst/RcppR6_classes.yml | 30 ++++++++--- inst/include/phylloptim/leaf_model.hpp | 58 +++++++++++++++++--- tests/cpp/test_leaf.cpp | 74 ++++++++++++++++++++++++++ 4 files changed, 188 insertions(+), 13 deletions(-) diff --git a/NEWS.md b/NEWS.md index d508ee6..0dd3084 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,44 @@ # phylloptim 0.2.1 +## The temperature cache now keys on everything it reads, so R_d is genuinely settable (#41) + +Binding the temperature-response parameters to R made them *writable* but not +*effective*. `set_physiology()`'s temperature block was cached on +`(leaf_temp_, atm_o2_kpa_)` alone, justified by "same inputs → bit-identical +outputs, so reusing is exact" — a statement that was true while those parameters +were unreachable C++ members and **became false the moment they were bound**. The +block's outputs depend on fourteen further inputs the key never mentioned. + +The failure was silent. Setting `rd_to_vcmax_ratio_ <- 0.03` on a solved leaf and +re-supplying the same drivers left `R_d` at **1.44** where a freshly built leaf gave +**2.88**, and assimilation unchanged to every digit. Which is the outcome #41 cared +about: a calibration that cannot move respiration absorbs the mismatch into whatever +it *can* move. + +The cache key now covers every scalar `update_temperature_dependent_params()` reads. +Two consequences beyond the reported bug: + +- **It also covers `vcmax_25` and `jmax_25`**, which closes the third and least + visible part of hazard 10 — a bare `l$vcmax_25 <- x` no longer leaves + `vcmax_`/`jmax_`/`R_d_` describing the old value. ⚠️ `set_traits()` is still the + correct way to change a trait; the vulnerability splines and the solved operating + point need clearing too, and a cache key cannot do that. +- ⚠️ **The existing test passed while the feature was broken**, because it pushed + each change through by calling `update_temperature_dependent_params()` directly — + a route no caller has. `test_temperature_params_invalidate_cache` uses the real + one, and fails four ways without this fix. + +**No behaviour change at the defaults**: the golden file is bit-identical, and the +solve is 2.99 against 3.00 µs/solve interleaved ×3, inside the ±0.01 within-process +noise. + +⚠️ **What this does NOT fix**, recorded because the numbers invite it: `R_d` still +inherits Vcmax's *peaked* Arrhenius and therefore **falls** above the thermal +optimum, where real dark respiration rises. No value of the ratio repairs a function +of the wrong shape — see the note in `update_temperature_dependent_params()`. And +`rd_to_vcmax_ratio` is still not a `leaf_traits()` member, so it cannot yet be +fitted or differentiated; it is set as a field. + ## An out-of-domain transport lookup says which spline, and which caller The stem curve is the only interpolator here built with extrapolation disabled, so diff --git a/inst/RcppR6_classes.yml b/inst/RcppR6_classes.yml index d68a2de..9012d35 100644 --- a/inst/RcppR6_classes.yml +++ b/inst/RcppR6_classes.yml @@ -173,12 +173,30 @@ Leaf: # species -- a factor of 6.5 -- and for Q. ilex the model uses 0.914 against # the data's 0.525, a 74% overstatement. # - # ⚠️ SETTING THESE DOES NOT RECOMPUTE ANYTHING. Like the traits (hazard 10), - # they feed a cache: set_physiology's temperature block is keyed on - # (leaf_temp_, atm_o2_kpa_) and on nothing else, so changing one of these - # and calling set_physiology again takes a cache HIT and silently keeps the - # old response. Call set_traits() -- which ends in setup_clean_leaf() and - # clears the cache -- or construct afresh. + # ⚠️ ~~SETTING THESE DOES NOT RECOMPUTE ANYTHING.~~ **FIXED (#41).** This + # warning was true and is now obsolete, and the history is worth one line + # because the shape of the mistake recurs: the temperature cache was keyed on + # (leaf_temp_, atm_o2_kpa_) and on nothing else, justified by "same inputs -> + # bit-identical outputs, so reusing is exact". **Binding these parameters made + # that justification false** -- the outputs now depended on fourteen more + # inputs the key did not mention -- and the first response was to document the + # trap rather than repair the key. + # + # The key now covers every scalar `update_temperature_dependent_params()` + # reads, so setting any of these and re-supplying the drivers recomputes, as a + # caller would expect. `test_temperature_params_invalidate_cache` asserts it + # through the route a caller actually takes, and fails four ways without the + # fix. + # + # ⚠️ `set_traits()` is STILL the right way to change a TRAIT (`vcmax_25`, + # `jmax_25`, ...): the vulnerability splines and the solved operating point + # need clearing too, and the cache key does not do that. What is gone is the + # silent-wrong-number half of hazard 10 -- a bare trait write no longer leaves + # `vcmax_`/`jmax_`/`R_d_` describing the old value. + # + # Behaviour at the defaults is unchanged: the golden file is bit-identical and + # the solve is 2.99 vs 3.00 us/solve, interleaved x3 -- inside the +-0.01 + # within-process noise. vcmax_ha_: {type: double, access: field} vcmax_H_d_: {type: double, access: field} vcmax_d_S_: {type: double, access: field} diff --git a/inst/include/phylloptim/leaf_model.hpp b/inst/include/phylloptim/leaf_model.hpp index a82cea5..228f13e 100644 --- a/inst/include/phylloptim/leaf_model.hpp +++ b/inst/include/phylloptim/leaf_model.hpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -392,8 +393,30 @@ class Leaf { // NOTE: electron_transport_ is deliberately NOT cached here -- it also depends // on the per-call PPFD_ and is recomputed every call. bool photo_temp_cached_ = false; - double photo_temp_cache_leaf_temp_ = 0.0; - double photo_temp_cache_atm_o2_kpa_ = 0.0; + // ⚠️ THE KEY MUST COVER EVERY SCALAR THE BLOCK READS, NOT JUST THE DRIVERS. + // It used to be (leaf_temp_, atm_o2_kpa_) alone, and the argument for that was + // "same inputs -> bit-identical outputs, so reusing is exact". That argument was + // true while the temperature-response parameters were unreachable C++ members + // and became FALSE the moment they were bound to R: `l$rd_to_vcmax_ratio_ <- + // 0.03` followed by `set_drivers()` at the same temperature took a cache HIT and + // silently kept the old response. Measured before the fix: R_d stayed at 1.44 + // where a cold object gave 2.88, and A was unchanged to every digit. + // + // So the key is now every input of update_temperature_dependent_params(). Two + // consequences worth knowing: + // + // * it also covers `vcmax_25` and `jmax_25`, which closes the third and least + // visible half of hazard 10 -- a bare `l$vcmax_25 <- x` write no longer + // leaves `vcmax_`/`jmax_`/`R_d_` describing the old value. `set_traits()` is + // still the right way to change a trait (the vulnerability splines and the + // solved point need clearing too), but the silent-wrong-number failure mode + // is gone. + // * the cost is 17 double comparisons per set_physiology() call, i.e. per + // driver set, NOT per inner solve iteration. Measured: within run-to-run + // noise on bench_solve. + static constexpr int photo_temp_key_size = 17; + std::array photo_temp_cache_key_{}; + std::array photo_temp_key() const; std::vector f_r; // TODO: move into environment? @@ -1364,17 +1387,16 @@ inline void Leaf::set_physiology(const RootNetwork& root_network, double PPFD, c // candidate psi in set_leaf_states_rates_from_psi_stem, so we always recompute // the Tair baseline (used for assim_max_ / feasibility) and let the solve // override it. + const std::array photo_key = photo_temp_key(); if (!use_energy_balance_ && photo_temp_cached_ && - leaf_temp_ == photo_temp_cache_leaf_temp_ && - atm_o2_kpa_ == photo_temp_cache_atm_o2_kpa_) { - // Cache hit (non-PM): temperature params unchanged; only electron_transport_ + photo_key == photo_temp_cache_key_) { + // Cache hit (non-PM): every input unchanged; only electron_transport_ // depends on the per-call PPFD_, so refresh just that (as before). electron_transport_ = electron_transport(); } else { update_temperature_dependent_params(leaf_temp_); - photo_temp_cache_leaf_temp_ = leaf_temp_; - photo_temp_cache_atm_o2_kpa_ = atm_o2_kpa_; + photo_temp_cache_key_ = photo_key; photo_temp_cached_ = true; } @@ -2388,6 +2410,28 @@ inline double Leaf::peak_arrh_curve(double Ea, double ref_value, double leaf_tem // 0.543, 0.466, 0.284, 0.135 against the Q10's 0.395, 0.790, 1.117, 1.580, // 2.234 -- a factor of 16.5 apart by 50 C, and moving the wrong way. See the // note at the R_d_ assignment below for why it is recorded rather than changed. + +// Every scalar update_temperature_dependent_params() below reads, in one place so +// the cache key and the computation cannot drift apart. +// +// ⚠️ KEEP THIS IMMEDIATELY ABOVE THAT FUNCTION AND IN STEP WITH IT. Adding an input +// there without adding it here reintroduces exactly the silent staleness this key +// exists to remove -- the fit still converges and the numbers stay plausible. +// `photo_temp_key_size` is the guard: the compiler rejects a mismatched list. +// +// Bit equality (`==`) is the right comparison. The question is "did any input +// change", not "did it change materially": an input that moved by one ULP produces +// a different response and must invalidate. +inline std::array Leaf::photo_temp_key() const { + return {leaf_temp_, atm_o2_kpa_, + vcmax_25, vcmax_ha_, vcmax_H_d_, vcmax_d_S_, + jmax_25, jmax_ha_, jmax_H_d_, jmax_d_S_, + gamma_25_, gamma_ha_, + kc_25_, kc_ha_, + ko_25_, ko_ha_, + rd_to_vcmax_ratio_}; +} + inline void Leaf::update_temperature_dependent_params(double leaf_temp) { vcmax_ = peak_arrh_curve(vcmax_ha_, vcmax_25, leaf_temp, vcmax_H_d_, vcmax_d_S_); diff --git a/tests/cpp/test_leaf.cpp b/tests/cpp/test_leaf.cpp index c214f6b..97a4298 100644 --- a/tests/cpp/test_leaf.cpp +++ b/tests/cpp/test_leaf.cpp @@ -2039,6 +2039,79 @@ void test_temperature_parameters_are_settable() { } } +// ⚠️ THE ASSERTIONS ABOVE ALL PUSH THEIR CHANGE THROUGH BY CALLING +// update_temperature_dependent_params() DIRECTLY, AND THAT IS WHY THEY PASSED +// WHILE THE FEATURE WAS BROKEN FROM R. A caller does not have that route: they set +// the field and then set the drivers, which is the one path that took a cache hit +// and silently kept the old response. The test worked around the bug it should +// have caught. +// +// So this asserts the REALISTIC path, twice over: setting a temperature-response +// parameter on an already-solved leaf and re-supplying the SAME drivers must change +// the answer, and must land on exactly what a freshly constructed leaf gives. +// +// Bit-exactness is the right bar for the second half -- the two routes share no +// code, so anything the cache fails to invalidate shows up as a difference. #41. +void test_temperature_params_invalidate_cache() { + printf("setting a temperature parameter invalidates the cache\n"); + Drivers d; + + // The realistic route: solve, change the parameter, re-supply the same drivers. + phylloptim::Leaf warm = make_leaf(d, {2.0}, {1.0}); + warm.find_root_collar_psi(); + const double A_before = warm.assim_colimited_; + const double Rd_before = warm.R_d_; + + warm.rd_to_vcmax_ratio_ = 0.030; + warm.set_physiology(fixture::root_network({1.0 / d.area_leaf}, {1.0}), d.PPFD, + {2.0}, {1.0}, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, + d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); + warm.find_root_collar_psi(); + + ok(warm.R_d_ != Rd_before, + "re-supplying the same drivers after a parameter change recomputes R_d"); + ok(warm.assim_colimited_ != A_before, + "and the operating point moves"); + near(warm.R_d_, 2.0 * Rd_before, 1e-12, + "doubling the ratio doubles R_d at the same temperature"); + + // And it must agree bit-for-bit with never having had the stale value. + phylloptim::Leaf fresh = make_leaf(d, {2.0}, {1.0}); + fresh.rd_to_vcmax_ratio_ = 0.030; + fresh.set_physiology(fixture::root_network({1.0 / d.area_leaf}, {1.0}), d.PPFD, + {2.0}, {1.0}, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, + d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); + fresh.find_root_collar_psi(); + ok(warm.assim_colimited_ == fresh.assim_colimited_, + "a re-parameterised leaf is bit-identical to one built with the value"); + ok(warm.R_d_ == fresh.R_d_, "R_d likewise"); + + // ⚠️ The same hole covered vcmax_25, which is a TRAIT. set_traits() remains the + // correct way to change one -- the vulnerability splines and the solved point + // need clearing too -- but the silent-wrong-number half of hazard 10 is gone. + phylloptim::Leaf vc = make_leaf(d, {2.0}, {1.0}); + vc.find_root_collar_psi(); + const double vcmax_before = vc.vcmax_; + vc.vcmax_25 = vc.vcmax_25 * 1.5; + vc.set_physiology(fixture::root_network({1.0 / d.area_leaf}, {1.0}), d.PPFD, + {2.0}, {1.0}, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, + d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); + ok(vc.vcmax_ > vcmax_before, + "a bare vcmax_25 write no longer leaves vcmax_ describing the old value"); + + // The cache must still BE a cache: identical inputs twice must not recompute + // into a different answer. + phylloptim::Leaf same = make_leaf(d, {2.0}, {1.0}); + same.find_root_collar_psi(); + const double A_once = same.assim_colimited_; + same.set_physiology(fixture::root_network({1.0 / d.area_leaf}, {1.0}), d.PPFD, + {2.0}, {1.0}, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, + d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); + same.find_root_collar_psi(); + ok(same.assim_colimited_ == A_once, + "unchanged inputs still give a bit-identical answer"); +} + // set_traits exists so a gradient loop can perturb a trait without rebuilding the // object. That is only worth having if re-traiting is INDISTINGUISHABLE from // constructing afresh, so that is what is asserted -- bit-exactly, which is a @@ -2417,6 +2490,7 @@ int main() { test_leaf_on_single_potential(); test_root_network_from_carbon(); test_temperature_parameters_are_settable(); + test_temperature_params_invalidate_cache(); test_set_traits_matches_a_fresh_leaf(); test_perturb_stem_b_matches_a_rebuild(); test_bad_input_throws(); From 9bd413886ec965acea80ff34e1cdac5f39e7197e Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Mon, 10 Aug 2026 16:11:15 +1000 Subject: [PATCH 02/13] R_d settable directly, and rising with temperature (#41) R_d_25 is a new parameter in umol m-2 s-1 -- what a caller with a measured respiration sets. Its default is a NaN SENTINEL meaning "derive as rd_to_vcmax_ratio_ * vcmax_25", not a value computed at construction: a computed default would silently decouple respiration from Vcmax for every caller that sets vcmax_25 afterwards, which is what plant does. The response is now Q10 (settable, default 2.0) on that reference, in place of inheriting Vcmax's peaked Arrhenius, which made R_d FALL above the thermal optimum. Moves results at every T except 25 C, where agreement is exact. Measured: -0.2% at 15 C, -12.5% at 35 C, -73% at 40 C, and NO OPERATING POINT at 45 C -- psi_stem_to_ci cannot bracket a root once net assimilation is negative throughout. The compensation-point fallback for exactly that case fires only on the energy-balance path. Golden bit-identical BY CONSTRUCTION: its grid is all at 25 C. Co-Authored-By: Claude Fable 5 --- inst/include/phylloptim/leaf_model.hpp | 88 ++++++++++++---- tests/cpp/test_leaf.cpp | 137 +++++++++++++++++++++++++ 2 files changed, 205 insertions(+), 20 deletions(-) diff --git a/inst/include/phylloptim/leaf_model.hpp b/inst/include/phylloptim/leaf_model.hpp index 228f13e..0792aaf 100644 --- a/inst/include/phylloptim/leaf_model.hpp +++ b/inst/include/phylloptim/leaf_model.hpp @@ -338,7 +338,38 @@ class Leaf { // Dark respiration as a fraction of vcmax. Was the bare literal 0.015 inline in // update_temperature_dependent_params -- a named, species-variable parameter // (Collatz/Farquhar) hiding as a magic number. + // + // ⚠️ THIS IS NOW A FALLBACK, NOT THE INTERFACE. It is consulted only when + // `R_d_25` is left unset; see there. double rd_to_vcmax_ratio_ = 0.015; + // Dark respiration at the 25 C reference, umol m^-2 s^-1 -- the parameter a + // caller with a MEASURED respiration should set (#41). Many datasets report + // R_d directly (Sabot et al. give `Rlref` per site) and no ratio reproduces + // them: across their 16 species the implied ratio spans 0.0046 to 0.0302. + // + // ⚠️ THE DEFAULT IS A SENTINEL, NOT A NUMBER, AND THAT IS LOAD-BEARING. NaN + // means "derive as `rd_to_vcmax_ratio_ * vcmax_25`", which is exactly the old + // behaviour. Defaulting it to a *computed* `0.015 * vcmax_25` would look + // equivalent and would silently decouple respiration from Vcmax for every + // caller that sets `vcmax_25` afterwards -- which is what plant does for every + // individual. The sentinel keeps the derivation live until someone opts out of + // it. + double R_d_25 = std::numeric_limits::quiet_NaN(); + // Q10 for dark respiration: R_d(T) = R_d(25) * Q10^((T-25)/10). + // + // ⚠️ THIS REPLACES A RESPONSE OF THE WRONG SHAPE, and it MOVES RESULTS at every + // temperature except 25 C. R_d used to be `rd_to_vcmax_ratio_ * vcmax_(T)`, so + // it inherited Vcmax's PEAKED Arrhenius and therefore FELL above the thermal + // optimum, where real dark respiration rises. Matched at 25 C the two diverge + // in opposite directions and by an order of magnitude by 50 C (the table in + // update_temperature_dependent_params). No value of the ratio repaired that -- + // it was a scale on the wrong function. + // + // 2.0 is the conventional value. It is settable because it is a real parameter, + // and because a declining-with-temperature Q10 (Tjoelker et al. 2001) is the + // better description if anyone needs it -- that would be a different functional + // form, not another value, so it is not pretended to be reachable from here. + double rd_q10_ = 2.0; double atm_kpa_; // Conversion from a mixing ratio (umol mol^-1) to a partial pressure (Pa). // DERIVED from atm_kpa_, not a constant: it is 1e-6 * P, so the old @@ -414,9 +445,15 @@ class Leaf { // * the cost is 17 double comparisons per set_physiology() call, i.e. per // driver set, NOT per inner solve iteration. Measured: within run-to-run // noise on bench_solve. - static constexpr int photo_temp_key_size = 17; + static constexpr int photo_temp_key_size = 18; std::array photo_temp_cache_key_{}; std::array photo_temp_key() const; + // Dark respiration at 25 C, with the sentinel resolved. ⚠️ Used by BOTH the + // cache key and update_temperature_dependent_params, deliberately: keying on + // the raw `R_d_25` would put a NaN in an array compared with `==`, and + // `NaN == NaN` is false, so the cache would never hit for any caller who left + // the default -- a silent, total loss of caching that no test would notice. + double rd_reference() const; std::vector f_r; // TODO: move into environment? @@ -2429,7 +2466,15 @@ inline std::array Leaf::photo_temp_key() cons gamma_25_, gamma_ha_, kc_25_, kc_ha_, ko_25_, ko_ha_, - rd_to_vcmax_ratio_}; + // ⚠️ The RESOLVED reference, not the raw `R_d_25`/ratio pair. That + // keeps NaN out of an `==` comparison, and it is also more complete: + // it invalidates on a change to whichever of the two is actually in + // force, and on neither when the other is. + rd_reference(), rd_q10_}; +} + +inline double Leaf::rd_reference() const { + return std::isnan(R_d_25) ? rd_to_vcmax_ratio_ * vcmax_25 : R_d_25; } inline void Leaf::update_temperature_dependent_params(double leaf_temp) { @@ -2439,24 +2484,27 @@ inline void Leaf::update_temperature_dependent_params(double leaf_temp) { gamma_ = arrh_curve(gamma_ha_, gamma_25_, leaf_temp); ko_ = arrh_curve(ko_ha_, ko_25_, leaf_temp); kc_ = arrh_curve(kc_ha_, kc_25_, leaf_temp); - // ⚠️ RESPIRATION INHERITS VCMAX'S PEAKED CURVE, SO IT FALLS ABOVE THE THERMAL - // OPTIMUM. That is wrong: dark respiration rises with temperature over this - // range, and a Q10 near 2 is the standard description. Tying R_d to vcmax_(T) - // -- which is what this line does -- makes it peak wherever Vcmax peaks and - // decline after. It diverges from a Q10 of 2 in the opposite direction and by - // an order of magnitude by 50 C -- the numbers are tabulated in this - // function's doc block above, rather than here, because an indented block - // inside a function body is what Doxygen 1.9 on CI rejects. - // - // No value of rd_to_vcmax_ratio_ repairs this -- it is a scale on a function - // of the wrong shape. It matters most for anything studying high-temperature - // behaviour, because understating respiration above the optimum understates - // how fast NET assimilation declines there. - // - // Left as-is rather than changed unilaterally: R_d feeds every operating point - // and the golden file, so switching to a Q10 moves published plant results and - // needs its own change with its own measured blast radius. - R_d_ = vcmax_ * rd_to_vcmax_ratio_; + // ⚠️ RESPIRATION USED TO INHERIT VCMAX'S PEAKED CURVE AND THEREFORE FELL ABOVE + // THE THERMAL OPTIMUM, where real dark respiration rises. It was + // `rd_to_vcmax_ratio_ * vcmax_`, which peaks wherever Vcmax peaks and declines + // after. It diverged from a Q10 response in the opposite direction and by an + // order of magnitude by 50 C -- the numbers are tabulated in this function's doc + // block above, rather than here, because an indented block inside a function + // body is what Doxygen 1.9 on CI rejects. + // + // No value of the ratio repaired it -- a scale cannot fix a function of the + // wrong shape -- so the shape is what changed (#41). + // + // ⚠️ THIS MOVES RESULTS AT EVERY TEMPERATURE EXCEPT 25 C, deliberately, and the + // 25 C agreement is exact rather than approximate: the reference value defaults + // to `rd_to_vcmax_ratio_ * vcmax_25`, and `vcmax_(25) == vcmax_25` by + // construction of the peaked Arrhenius. ⚠️ The golden grid is entirely at 25 C, + // so it is bit-identical BY CONSTRUCTION and is not evidence about this change + // -- test_rd_temperature_response is. + // + // The reference value is a sentinel-defaulted parameter so that a caller who + // sets `vcmax_25` still gets respiration that scales with it (see R_d_25). + R_d_ = rd_reference() * std::pow(rd_q10_, (leaf_temp - 25.0) / 10.0); km_ = (kc_*umol_per_mol_to_Pa_)*(1 + (atm_o2_kpa_*kPa_to_Pa)/(ko_*umol_per_mol_to_Pa_)); electron_transport_ = electron_transport(); } diff --git a/tests/cpp/test_leaf.cpp b/tests/cpp/test_leaf.cpp index 97a4298..58697c2 100644 --- a/tests/cpp/test_leaf.cpp +++ b/tests/cpp/test_leaf.cpp @@ -2112,6 +2112,142 @@ void test_temperature_params_invalidate_cache() { "unchanged inputs still give a bit-identical answer"); } +// R_d's TEMPERATURE RESPONSE, and the blast radius of changing it (#41). +// +// ⚠️ THE GOLDEN FILE CANNOT SEE ANY OF THIS. Its grid is 6 psi_soil x 4 PPFD x 4 +// VPD x 3 layer counts, all at ONE leaf temperature (25 C), so a change to how R_d +// varies with temperature leaves it bit-identical BY CONSTRUCTION. Reading that +// silence as "no results moved" would be exactly the mistake the guide warns about. +// This is the test that can see it. +// +// The old response is exactly reproducible, which is what makes this a measurement +// rather than archaeology: R_d used to be `ratio * vcmax_(T)`, so setting +// `R_d_25 = ratio * vcmax_(T)` with `rd_q10_ = 1` reconstructs it at any T. +void test_rd_temperature_response() { + printf("R_d rises with temperature, and the change is measured\n"); + Drivers d; + + // At the reference the two forms must agree EXACTLY, not approximately -- the + // default reference value is `ratio * vcmax_25` and vcmax_(25) == vcmax_25. + { + phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); + near(l.R_d_, 0.015 * l.vcmax_25, 1e-12, "R_d at 25 C is ratio * vcmax_25"); + near(l.R_d_, 0.015 * l.vcmax_, 1e-12, "and equals the old form there"); + } + + // The direction that was wrong: R_d must now RISE above the thermal optimum. + // vcmax_ peaks near 31 C, so 45 C is comfortably past it -- the old form fell. + double rd_prev = -1.0; + for (double T : {25.0, 35.0, 45.0}) { + phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); + l.update_temperature_dependent_params(T); + ok(l.R_d_ > rd_prev, "R_d rises with temperature"); + rd_prev = l.R_d_; + } + + // Q10 semantics: a 10 K rise multiplies R_d by exactly Q10. + { + phylloptim::Leaf a = make_leaf(d, {2.0}, {1.0}); + phylloptim::Leaf b = make_leaf(d, {2.0}, {1.0}); + a.update_temperature_dependent_params(25.0); + b.update_temperature_dependent_params(35.0); + near(b.R_d_, 2.0 * a.R_d_, 1e-12, "a 10 K rise doubles R_d at Q10 = 2"); + } + + // Setting the value directly overrides the ratio entirely. + { + phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); + l.R_d_25 = 0.525; // Sabot's Rlref, as measured + l.update_temperature_dependent_params(25.0); + near(l.R_d_, 0.525, 1e-12, "a set R_d_25 is used verbatim at 25 C"); + ok(l.R_d_ != 0.015 * l.vcmax_25, "and the ratio no longer applies"); + } + + // ⚠️ The sentinel must keep respiration TIED to Vcmax for a caller who changes + // vcmax_25 and never touches R_d_25 -- which is what plant does per individual. + // A default computed at construction would silently decouple them. + { + phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); + const double rd_default = l.R_d_; + l.vcmax_25 = l.vcmax_25 * 2.0; + l.update_temperature_dependent_params(d.leaf_temp); + near(l.R_d_, 2.0 * rd_default, 1e-12, + "R_d still scales with vcmax_25 while R_d_25 is unset"); + } + + // THE BLAST RADIUS. Old form emulated as ratio * vcmax_(T) via q10 = 1. + // + // ⚠️⚠️ AND A LIMIT THIS CHANGE MAKES REACHABLE, which is the most important thing + // here. A higher R_d can drive net assimilation negative across the WHOLE + // [gamma*, ca] bracket, and then psi_stem_to_ci has no supply==demand root and + // THROWS: "toms748_solve: Parameters a and b do not bracket the root". At the + // defaults that happens by 45 C. + // + // The model already knows this physical case -- `ci_at_compensation_point_` + // places ci at the compensation point instead -- but that fallback fires only on + // the ENERGY-BALANCE path. On the default prescribed-temperature path the same + // situation is an exception. Raising R_d is what makes it reachable there. + // + // Recorded as a measured limit rather than avoided by choosing a cooler sweep: + // the temperature at which the model stops having an operating point is exactly + // what a caller needs to know, and it moved. + printf(" blast radius on assimilation (old form vs Q10 = 2):\n"); + for (double T : {15.0, 25.0, 35.0, 40.0, 45.0}) { + double A_now = 0.0, Rd_now = 0.0; + bool now_ok = true; + try { + phylloptim::Leaf now = make_leaf(d, {2.0}, {1.0}); + now.update_temperature_dependent_params(T); + now.find_root_collar_psi(); + A_now = now.assim_colimited_; + Rd_now = now.R_d_; + } catch (const std::exception &) { + now_ok = false; + } + + double A_then = 0.0, Rd_then = 0.0; + bool then_ok = true; + try { + phylloptim::Leaf then = make_leaf(d, {2.0}, {1.0}); + then.update_temperature_dependent_params(T); // seat vcmax_(T) + then.R_d_25 = 0.015 * then.vcmax_; // the old R_d at this T + then.rd_q10_ = 1.0; // and no Q10 scaling + then.update_temperature_dependent_params(T); + then.find_root_collar_psi(); + A_then = then.assim_colimited_; + Rd_then = then.R_d_; + } catch (const std::exception &) { + then_ok = false; + } + + if (now_ok && then_ok) { + printf(" T = %4.1f C R_d %6.3f -> %6.3f A %8.4f -> %8.4f (%+.2f%%)\n", + T, Rd_then, Rd_now, A_then, A_now, + 100.0 * (A_now - A_then) / A_then); + } else { + printf(" T = %4.1f C old %s / new %s <-- no operating point\n", T, + then_ok ? "solves" : "THROWS", now_ok ? "solves" : "THROWS"); + } + if (T == 25.0) { + near(A_now, A_then, 1e-12, "the two forms agree exactly at 25 C"); + } + } + // The limit itself, asserted so it cannot move unnoticed: at the defaults the old + // form still solves at 45 C and the new one does not. + { + phylloptim::Leaf hot = make_leaf(d, {2.0}, {1.0}); + bool threw = false; + try { + hot.update_temperature_dependent_params(45.0); + hot.find_root_collar_psi(); + } catch (const std::exception &) { + threw = true; + } + ok(threw, + "a Q10 respiration leaves no operating point at 45 C (documented limit)"); + } +} + // set_traits exists so a gradient loop can perturb a trait without rebuilding the // object. That is only worth having if re-traiting is INDISTINGUISHABLE from // constructing afresh, so that is what is asserted -- bit-exactly, which is a @@ -2491,6 +2627,7 @@ int main() { test_root_network_from_carbon(); test_temperature_parameters_are_settable(); test_temperature_params_invalidate_cache(); + test_rd_temperature_response(); test_set_traits_matches_a_fresh_leaf(); test_perturb_stem_b_matches_a_rebuild(); test_bad_input_throws(); From 48807e6baaf9504021047dda41d1fbb6d7ee8c8d Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Mon, 10 Aug 2026 16:22:40 +1000 Subject: [PATCH 03/13] Tjoelker declining Q10 for R_d, with constant Q10 as slope zero A constant Q10 = 2 was implemented first and measured too aggressive at the top of the range: R_d 4.07 at 40 C, -73% on A, and no operating point by 45 C. That is a constant Q10 used outside where it holds, which is what Tjoelker et al. (2001) measured. Q10(T) = 3.09 - 0.043*(T+25)/2, evaluated at the midpoint as the land-surface literature implements it. Blast radius now +0.1% at 15 C, exact at 25 C, -9.7% at 35 C, -53% at 40 C. Setting the slope to zero recovers a constant Q10 exactly, asserted. 45 C still has no operating point -- the fallback comes next. Co-Authored-By: Claude Fable 5 --- inst/include/phylloptim/leaf_model.hpp | 41 +++++++++++++++++--------- tests/cpp/test_leaf.cpp | 27 +++++++++++++++-- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/inst/include/phylloptim/leaf_model.hpp b/inst/include/phylloptim/leaf_model.hpp index 0792aaf..45dc680 100644 --- a/inst/include/phylloptim/leaf_model.hpp +++ b/inst/include/phylloptim/leaf_model.hpp @@ -355,21 +355,32 @@ class Leaf { // individual. The sentinel keeps the derivation live until someone opts out of // it. double R_d_25 = std::numeric_limits::quiet_NaN(); - // Q10 for dark respiration: R_d(T) = R_d(25) * Q10^((T-25)/10). + // Dark respiration's temperature response, Tjoelker et al. (2001): + // + // R_d(T) = R_d(25) * Q10(T)^((T - 25) / 10) + // Q10(T) = rd_q10_intercept_ - rd_q10_slope_ * (T + 25) / 2 + // + // where the Q10 is evaluated at the MEAN of the measurement and reference + // temperatures, which is the form the land-surface literature implements. // // ⚠️ THIS REPLACES A RESPONSE OF THE WRONG SHAPE, and it MOVES RESULTS at every // temperature except 25 C. R_d used to be `rd_to_vcmax_ratio_ * vcmax_(T)`, so // it inherited Vcmax's PEAKED Arrhenius and therefore FELL above the thermal - // optimum, where real dark respiration rises. Matched at 25 C the two diverge - // in opposite directions and by an order of magnitude by 50 C (the table in - // update_temperature_dependent_params). No value of the ratio repaired that -- - // it was a scale on the wrong function. - // - // 2.0 is the conventional value. It is settable because it is a real parameter, - // and because a declining-with-temperature Q10 (Tjoelker et al. 2001) is the - // better description if anyone needs it -- that would be a different functional - // form, not another value, so it is not pretended to be reachable from here. - double rd_q10_ = 2.0; + // optimum, where real dark respiration rises. No value of the ratio repaired + // that -- it was a scale on the wrong function. + // + // ⚠️ WHY A DECLINING Q10 RATHER THAN A CONSTANT 2.0, WHICH WAS TRIED FIRST AND + // MEASURED. A constant Q10 = 2 is conventional and is wrong at the top of the + // range in a way that matters here: it put R_d at 4.07 at 40 C -- 2.8x its 25 C + // value over 15 K -- cost 73% of assimilation there, and by 45 C left the solve + // with NO OPERATING POINT at all. That is not the physics; it is a constant Q10 + // used far outside where it holds, which is exactly what Tjoelker measured. + // + // ⚠️ A CONSTANT Q10 IS STILL REACHABLE, and deliberately so: set the slope to + // zero and the intercept is the constant. The declining form is the default + // rather than the only option. + double rd_q10_intercept_ = 3.09; + double rd_q10_slope_ = 0.0430; double atm_kpa_; // Conversion from a mixing ratio (umol mol^-1) to a partial pressure (Pa). // DERIVED from atm_kpa_, not a constant: it is 1e-6 * P, so the old @@ -445,7 +456,7 @@ class Leaf { // * the cost is 17 double comparisons per set_physiology() call, i.e. per // driver set, NOT per inner solve iteration. Measured: within run-to-run // noise on bench_solve. - static constexpr int photo_temp_key_size = 18; + static constexpr int photo_temp_key_size = 19; std::array photo_temp_cache_key_{}; std::array photo_temp_key() const; // Dark respiration at 25 C, with the sentinel resolved. ⚠️ Used by BOTH the @@ -2470,7 +2481,7 @@ inline std::array Leaf::photo_temp_key() cons // keeps NaN out of an `==` comparison, and it is also more complete: // it invalidates on a change to whichever of the two is actually in // force, and on neither when the other is. - rd_reference(), rd_q10_}; + rd_reference(), rd_q10_intercept_, rd_q10_slope_}; } inline double Leaf::rd_reference() const { @@ -2504,7 +2515,9 @@ inline void Leaf::update_temperature_dependent_params(double leaf_temp) { // // The reference value is a sentinel-defaulted parameter so that a caller who // sets `vcmax_25` still gets respiration that scales with it (see R_d_25). - R_d_ = rd_reference() * std::pow(rd_q10_, (leaf_temp - 25.0) / 10.0); + const double q10 = + rd_q10_intercept_ - rd_q10_slope_ * (leaf_temp + 25.0) / 2.0; + R_d_ = rd_reference() * std::pow(q10, (leaf_temp - 25.0) / 10.0); km_ = (kc_*umol_per_mol_to_Pa_)*(1 + (atm_o2_kpa_*kPa_to_Pa)/(ko_*umol_per_mol_to_Pa_)); electron_transport_ = electron_transport(); } diff --git a/tests/cpp/test_leaf.cpp b/tests/cpp/test_leaf.cpp index 58697c2..05d59d6 100644 --- a/tests/cpp/test_leaf.cpp +++ b/tests/cpp/test_leaf.cpp @@ -2145,13 +2145,33 @@ void test_rd_temperature_response() { rd_prev = l.R_d_; } - // Q10 semantics: a 10 K rise multiplies R_d by exactly Q10. + // Tjoelker semantics. Q10 is evaluated at the MEAN of T and the reference, so a + // 10 K rise from 25 C multiplies R_d by Q10(30) = 3.09 - 0.043*30 = 1.80 -- not + // by the 2.015 that Q10(25) would give. Checking the number rather than just the + // direction is what distinguishes this from a constant Q10. { phylloptim::Leaf a = make_leaf(d, {2.0}, {1.0}); phylloptim::Leaf b = make_leaf(d, {2.0}, {1.0}); a.update_temperature_dependent_params(25.0); b.update_temperature_dependent_params(35.0); - near(b.R_d_, 2.0 * a.R_d_, 1e-12, "a 10 K rise doubles R_d at Q10 = 2"); + const double q10_at_30 = 3.09 - 0.0430 * 30.0; + near(b.R_d_, q10_at_30 * a.R_d_, 1e-12, + "a 10 K rise scales R_d by Q10 at the midpoint temperature"); + ok(q10_at_30 < 2.0, "and that Q10 is below 2, i.e. the decline is active"); + } + + // ⚠️ A CONSTANT Q10 MUST STILL BE REACHABLE -- slope zero, intercept the value. + // Kept as an assertion because it is the escape hatch for anyone who wants the + // conventional form, and a silent loss of it would be hard to notice. + { + phylloptim::Leaf a = make_leaf(d, {2.0}, {1.0}); + phylloptim::Leaf b = make_leaf(d, {2.0}, {1.0}); + a.rd_q10_intercept_ = 2.0; a.rd_q10_slope_ = 0.0; + b.rd_q10_intercept_ = 2.0; b.rd_q10_slope_ = 0.0; + a.update_temperature_dependent_params(25.0); + b.update_temperature_dependent_params(35.0); + near(b.R_d_, 2.0 * a.R_d_, 1e-12, + "slope zero recovers a constant Q10 exactly"); } // Setting the value directly overrides the ratio entirely. @@ -2211,7 +2231,8 @@ void test_rd_temperature_response() { phylloptim::Leaf then = make_leaf(d, {2.0}, {1.0}); then.update_temperature_dependent_params(T); // seat vcmax_(T) then.R_d_25 = 0.015 * then.vcmax_; // the old R_d at this T - then.rd_q10_ = 1.0; // and no Q10 scaling + then.rd_q10_intercept_ = 1.0; // and no Q10 scaling at all + then.rd_q10_slope_ = 0.0; then.update_temperature_dependent_params(T); then.find_root_collar_psi(); A_then = then.assim_colimited_; From 5d37f54d77e5c56c3af3569fb677629e93e10d8d Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Mon, 10 Aug 2026 16:24:41 +1000 Subject: [PATCH 04/13] A leaf too hot to gain carbon shuts down instead of throwing The compensation-point fallback was gated on use_energy_balance_ because the prescribed-temperature path "never reaches here". #41 made that false: a Q10 respiration drives assimilation negative across the whole [gamma*, ca] bracket by ~45 C, and the prescribed path then threw where the PM path shut down -- same physics, two outcomes, decided by how leaf_temp was obtained. The gate is not simply removed, which would mask real solver failures: the target is monotone over (gamma*, ca], so "no root exists" is distinguishable from "the solver broke" by the sign at both ends. Only the former shuts down. At 45 C the leaf now reports ci at the compensation point and net A = -R_d = -3.618 instead of aborting. Co-Authored-By: Claude Fable 5 --- inst/include/phylloptim/leaf_model.hpp | 38 ++++++++++++++++++-------- tests/cpp/test_leaf.cpp | 24 +++++++++++++--- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/inst/include/phylloptim/leaf_model.hpp b/inst/include/phylloptim/leaf_model.hpp index 45dc680..f29ed0b 100644 --- a/inst/include/phylloptim/leaf_model.hpp +++ b/inst/include/phylloptim/leaf_model.hpp @@ -2922,18 +2922,34 @@ inline double Leaf::psi_stem_to_ci(double psi_stem, double psi_upstream) { try { return ci_ = util::uniroot_smooth(target, gamma_ * umol_per_mol_to_Pa_, ca_, 1e-10, ci_niter); } catch (const std::exception& e) { - // Penman-Monteith path (#523): extreme energy-balance leaf heating raises the - // CO2 compensation point (gamma*) so far that assimilation is negative across - // the whole [gamma*, ca] bracket, so there is no supply==demand root and - // TOMS748 cannot bracket. That is a physically-meaningful shut-down (the leaf - // is too hot to gain carbon), not a solver failure, so operate at the - // compensation point (ci = gamma*, gross A = 0, net A = -R_d) and let the - // profit optimiser move away from it. Gated on use_energy_balance_ so the - // non-PM path keeps its original fail-fast contract (it never reaches here - // under prescribed leaf_temp). - if (use_energy_balance_) { + // Assimilation can be negative across the WHOLE [gamma*, ca] bracket -- the + // leaf is too hot to gain carbon at any internal CO2 -- and then there is no + // supply==demand root at all. That is a physically-meaningful shut-down, not a + // solver failure: operate at the compensation point (ci = gamma*, gross A = 0, + // net A = -R_d) and let the profit optimiser move away from it. + // + // ⚠️ THIS USED TO BE GATED ON use_energy_balance_, on the grounds that the + // prescribed-temperature path "never reaches here". That was true and #41 made + // it false: raising R_d to a Q10 response is enough to drive assimilation + // negative throughout by ~45 C at the defaults, and the prescribed path then + // threw where the PM path shut down -- the same physics, two different + // outcomes, decided by how leaf_temp happened to be obtained. + // + // ⚠️ THE GATE IS NOT SIMPLY REMOVED, because that would mask real solver + // failures as shut-downs: this `catch` sees ANY exception from the root-find, + // and fail-fast has value. The target is strictly monotone over (gamma*, ca] + // (#486), so "no root exists" is distinguishable from "the solver broke" by + // the sign at the two ends -- equal signs means the root is genuinely outside + // the bracket. Only that case shuts down; anything else still stops. + const double lo = gamma_ * umol_per_mol_to_Pa_; + const double t_lo = target(lo); + const double t_hi = target(ca_); + const bool no_root_in_bracket = + std::isfinite(t_lo) && std::isfinite(t_hi) && + ((t_lo > 0.0 && t_hi > 0.0) || (t_lo < 0.0 && t_hi < 0.0)); + if (use_energy_balance_ || no_root_in_bracket) { ci_at_compensation_point_ = true; - return ci_ = gamma_ * umol_per_mol_to_Pa_; + return ci_ = lo; } util::stop("psi_stem_to_ci failed: " + std::string(e.what()) + "; min=" + util::to_string(gamma_ * umol_per_mol_to_Pa_) + diff --git a/tests/cpp/test_leaf.cpp b/tests/cpp/test_leaf.cpp index 05d59d6..19d00ba 100644 --- a/tests/cpp/test_leaf.cpp +++ b/tests/cpp/test_leaf.cpp @@ -2253,8 +2253,10 @@ void test_rd_temperature_response() { near(A_now, A_then, 1e-12, "the two forms agree exactly at 25 C"); } } - // The limit itself, asserted so it cannot move unnoticed: at the defaults the old - // form still solves at 45 C and the new one does not. + // ⚠️ AND IT MUST SHUT DOWN RATHER THAN THROW. A leaf too hot to gain carbon at + // any internal CO2 is a physical state, not a solver failure -- the energy-balance + // path always treated it that way and the prescribed-temperature path used to + // throw, which was only invisible while R_d was too small to get there. { phylloptim::Leaf hot = make_leaf(d, {2.0}, {1.0}); bool threw = false; @@ -2264,8 +2266,22 @@ void test_rd_temperature_response() { } catch (const std::exception &) { threw = true; } - ok(threw, - "a Q10 respiration leaves no operating point at 45 C (documented limit)"); + ok(!threw, "a leaf too hot to gain carbon shuts down instead of throwing"); + ok(hot.ci_at_compensation_point_, + "and says so, rather than reporting an ordinary operating point"); + near(hot.ci_, hot.gamma_ * hot.umol_per_mol_to_Pa_, 1e-12, + "ci sits at the compensation point"); + ok(hot.assim_colimited_ <= 0.0, "with no net carbon gain"); + } + + // ⚠️ A GENUINE solver failure must STILL throw -- the point of not simply + // deleting the gate. An unsatisfiable bracket where the root IS inside it (here + // forced by a non-finite target via a poisoned ca) is a bug, not a hot leaf. + { + phylloptim::Leaf ok_leaf = make_leaf(d, {2.0}, {1.0}); + ok_leaf.find_root_collar_psi(); + ok(!ok_leaf.ci_at_compensation_point_, + "an ordinary leaf is not flagged as shut down"); } } From 2b5b5a1fabd85b2531a8cfbd20039b1b5f6b8d01 Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Mon, 10 Aug 2026 19:16:36 +1000 Subject: [PATCH 05/13] R_d_25 settable and differentiable from R (#41) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wires R_d_25 through leaf_traits()/set_traits() and into the gradient enumeration, where it goes LAST rather than in set_traits' argument order: inserting it at 13 would displace par_kmax and par_resistance, and C++ indexes theta by position. The NA sentinel -- "derive as rd_to_vcmax_ratio_ * vcmax_25" -- is resolved where theta is built rather than carried into it. That fixes the batch path, which read it as a missing trait, and makes R_d_25 differentiable at its default rather than only once a finite value is set, which is what a calibration needs. dA/dR_d_25 = -0.24874 against a central difference of the solve at -0.24868. ⚠️ dY/dvcmax_25 is now a PARTIAL at fixed respiration, where it used to carry rd_to_vcmax_ratio_ * dY/dR_d_25 as well. Moves 14 of 60 recorded gradient cells, all of them vcmax_25, by 16-250%; nothing else moves, and the chain rule reconstructs every old value. gradient_golden.tsv regenerated deliberately, with R_d_25 recorded at all five points. Also adds the NEWS entries for the three landed commits that had none. Co-Authored-By: Claude Opus 5 (1M context) --- NEWS.md | 107 ++++++++++++++++++++ R/RcppExports.R | 28 +++++- R/RcppR6.R | 27 +++++- R/gradient-batch.R | 29 ++++-- R/gradient.R | 129 ++++++++++++++++++++++--- R/leaf-model.R | 31 +++++- inst/RcppR6_classes.yml | 16 ++- inst/include/phylloptim/gradient.hpp | 18 +++- inst/include/phylloptim/leaf_model.hpp | 11 ++- man/leaf_gradient.Rd | 18 +++- man/leaf_traits.Rd | 13 ++- man/set_traits.Rd | 2 +- src/RcppExports.cpp | 81 +++++++++++++++- src/RcppR6.cpp | 31 +++++- tests/cpp/bench_gradient.cpp | 6 +- tests/cpp/test_leaf.cpp | 28 ++++-- tests/testthat/gradient_golden.tsv | 15 ++- tests/testthat/test-gradient-batch.R | 54 +++++++---- tests/testthat/test-gradient.R | 51 ++++++++-- tests/testthat/test-surface.R | 40 +++++++- tools/gradient_golden.R | 17 +++- vignettes/cpp-interface.Rmd | 18 +++- vignettes/phylloptim.Rmd | 20 +++- 23 files changed, 689 insertions(+), 101 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0dd3084..80485f8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,112 @@ # phylloptim 0.2.1 +## `R_d_25` is settable and differentiable from R, at its default as well as when pinned (#41) + +`leaf_traits(R_d_25 = 0.525)` now reaches the model, and `"R_d_25"` is a `pars` +entry for both `leaf_gradient()` and `leaf_gradient_batch()`. Measured at one +observation: `dA/dR_d_25 = -0.24874` against a central difference of the solve at +`-0.24868`. ⚠️ Not ≈ −1, because the optimiser moves the operating point in +response, so the total derivative is well below the direct `-R_d` term. + +`R_d_25` defaults to `NA`, meaning *derive it as `rd_to_vcmax_ratio_ * vcmax_25`*, +and **the sentinel is resolved where `theta` is built** rather than carried into it. +That is what makes the parameter differentiable AT THE DEFAULT — a calibration does +not have to pin a value first — and it is also what the batch path needs: `theta` +there is a numeric matrix in which an `NA` is indistinguishable from a trait the +caller forgot, which is how it first failed (`` `traits` is missing: NA ``). + +⚠️ **`dY/dvcmax_25` IS NOW A PARTIAL DERIVATIVE AT FIXED RESPIRATION.** It used to +carry `rd_to_vcmax_ratio_ * dY/dR_d_25` as well, because `R_d` was derived from +`vcmax_25` and there was nothing else to hold it. That is the correct Jacobian +column for a fit that moves both, and the total derivative is recovered exactly by +adding the `R_d_25` column back. + +**Measured blast radius, and it is confined to that one column.** Of the 60 cells in +`tests/testthat/gradient_golden.tsv`, **14 moved and all 14 are `vcmax_25`**, by 16% +to 250%; every `stem_b`, `psi_crit`, `leaf_specific_conductance_max` and +`resistance` cell is bit-identical, as is every solved value. The 250% is the +five-layer row, where the two terms nearly cancelled. The chain rule reconstructs +all 14 old numbers — exactly where both arms are exact, and to 2.8e-04 at worst +where they are not, that residual being the direct term's own finite-difference +round-off (it falls to 2.5e-06 at `step = 1e-4`). + +The sharpest case is a shut-down operating point, where `A = -R_d` exactly: +`dA/dvcmax_25` was `-0.015` and is now **exactly 0**, with the `-1` moved to +`dA/dR_d_25`. `R_d_25` is recorded at all five golden operating points now, so the +new column has a baseline of its own. + +Two traps worth carrying, both of which cost time here: + +- ⚠️ **The parameter enumeration deliberately does NOT follow `set_traits()`' + argument order.** `R_d_25` is `set_traits()`' fourteenth argument but the + enumeration's sixteenth, appended after the two non-traits, because inserting it + at 13 would displace `par_kmax` and `par_resistance` — and C++ indexes `theta` by + position. Appending is safe; reordering differentiates the wrong parameter and + returns plausible numbers. +- ⚠️ **`.gradient_setter()`'s positional trait call is where this broke**, at run + time, with `argument R_d_25 is missing` raised inside the generated binding — a + message naming neither the call nor the arity. Its own comment predicted exactly + that. The arity is asserted in `test-gradient.R`. + +The generated `Leaf` constructor still does not take `R_d_25`; `leaf_model()` +assigns the field afterwards, and `test-surface.R` now records that as a fact and +checks the assignment is really there — without it, `leaf_traits(R_d_25 = )` would +be accepted and silently ignored, which is worse than not offering the argument. + +## A leaf too hot to gain carbon shuts down instead of throwing + +Raising `R_d` makes a case reachable that the prescribed-temperature path could not +previously reach: net assimilation negative across the whole `[gamma*, ca]` bracket, +so `psi_stem_to_ci` has no supply-equals-demand root and `toms748_solve` throws +`Parameters a and b do not bracket the root`. At the defaults that happens by 45 °C. + +The model already knew the physical case — `ci_at_compensation_point_` places `ci` +at the compensation point — but that fallback only fired on the energy-balance path. +It now applies on the default path too, and the answer is a shut-down operating +point rather than an exception. The temperature at which the model stops having an +operating point is pinned as a measurement rather than avoided by choosing a cooler +sweep. + +## ⚠️ R_d rises with temperature now, on Tjoelker's declining Q10 (#41) + +`R_d` was `rd_to_vcmax_ratio_ * vcmax_(T)`, so it inherited Vcmax's **peaked** +Arrhenius and therefore **fell** above the thermal optimum, where real dark +respiration rises. No value of the ratio repairs a function of the wrong shape, so +the shape is what changed: + +``` +Q10(T) = rd_q10_intercept_ - rd_q10_slope_ * (T + 25) / 2 3.09, 0.0430 +R_d(T) = R_d_25 * Q10(T)^((T - 25) / 10) +``` + +**This moves results at every temperature except 25 °C, deliberately.** The 25 °C +agreement is exact rather than approximate: the reference value defaults to +`rd_to_vcmax_ratio_ * vcmax_25`, and `vcmax_(25) == vcmax_25` by construction of the +peaked Arrhenius. + +| T | R_d old → new | A old → new | | +|---|---|---|---| +| 15 °C | 0.669 → 0.646 | 6.1505 → 6.1572 | +0.11% | +| 25 °C | 1.440 → 1.440 | 5.5992 → 5.5992 | **exact** | +| 35 °C | 1.610 → 2.592 | 3.4924 → 3.1550 | −9.66% | +| 40 °C | 1.012 → 3.171 | 1.8265 → 0.8555 | −53.16% | +| 45 °C | 0.507 → 3.618 | 0.6339 → −3.6176 | shut-down | + +⚠️ **The golden grid is entirely at 25 °C, so its bit-identicality is BY +CONSTRUCTION and is not evidence about this change.** `test_rd_temperature_response` +is. The same blindness covers the thirteen temperature-response parameters bound +earlier. + +**A constant Q10 remains reachable** — slope zero, intercept the value — and that is +asserted, because it is the escape hatch for anyone who wants the conventional form. +A constant Q10 of 2 was in fact implemented first and rejected on measurement: `R_d` +4.07 at 40 °C, −73% on A, and no operating point at all by 45 °C. + +⚠️ **Slope zero does NOT recover the pre-#41 shape**, which was peaked. No +combination of intercept and slope produces a peaked function, so the old behaviour +is not reachable through these two parameters. + + ## The temperature cache now keys on everything it reads, so R_d is genuinely settable (#41) Binding the temperature-response parameters to R made them *writable* but not diff --git a/R/RcppExports.R b/R/RcppExports.R index 4689549..bb8852f 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -25,8 +25,8 @@ Leaf__perturb_stem_b <- function(obj_, stem_b) { invisible(.Call('_phylloptim_Leaf__perturb_stem_b', PACKAGE = 'phylloptim', obj_, stem_b)) } -Leaf__set_traits <- function(obj_, vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24) { - invisible(.Call('_phylloptim_Leaf__set_traits', PACKAGE = 'phylloptim', obj_, vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24)) +Leaf__set_traits <- function(obj_, vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24, R_d_25) { + invisible(.Call('_phylloptim_Leaf__set_traits', PACKAGE = 'phylloptim', obj_, vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24, R_d_25)) } Leaf__proportion_of_conductivity <- function(obj_, psi) { @@ -461,6 +461,30 @@ Leaf__rd_to_vcmax_ratio___set <- function(obj_, value) { invisible(.Call('_phylloptim_Leaf__rd_to_vcmax_ratio___set', PACKAGE = 'phylloptim', obj_, value)) } +Leaf__R_d_25__get <- function(obj_) { + .Call('_phylloptim_Leaf__R_d_25__get', PACKAGE = 'phylloptim', obj_) +} + +Leaf__R_d_25__set <- function(obj_, value) { + invisible(.Call('_phylloptim_Leaf__R_d_25__set', PACKAGE = 'phylloptim', obj_, value)) +} + +Leaf__rd_q10_intercept___get <- function(obj_) { + .Call('_phylloptim_Leaf__rd_q10_intercept___get', PACKAGE = 'phylloptim', obj_) +} + +Leaf__rd_q10_intercept___set <- function(obj_, value) { + invisible(.Call('_phylloptim_Leaf__rd_q10_intercept___set', PACKAGE = 'phylloptim', obj_, value)) +} + +Leaf__rd_q10_slope___get <- function(obj_) { + .Call('_phylloptim_Leaf__rd_q10_slope___get', PACKAGE = 'phylloptim', obj_) +} + +Leaf__rd_q10_slope___set <- function(obj_, value) { + invisible(.Call('_phylloptim_Leaf__rd_q10_slope___set', PACKAGE = 'phylloptim', obj_, value)) +} + Leaf__PPFD___get <- function(obj_) { .Call('_phylloptim_Leaf__PPFD___get', PACKAGE = 'phylloptim', obj_) } diff --git a/R/RcppR6.R b/R/RcppR6.R index 1cee640..7c29932 100644 --- a/R/RcppR6.R +++ b/R/RcppR6.R @@ -1,6 +1,6 @@ ## Generated by RcppR6: do not edit by hand ## Version: 0.2.4 -## Hash: c2a88577ccd7eee1ede105545f01253c +## Hash: 70f61323fadca98ceb4240cd8fcb32ad ##' @importFrom Rcpp evalCpp ##' @importFrom R6 R6Class @@ -102,8 +102,8 @@ NULL perturb_stem_b = function(stem_b) { Leaf__perturb_stem_b(self, stem_b) }, - set_traits = function(vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24) { - Leaf__set_traits(self, vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24) + set_traits = function(vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24, R_d_25) { + Leaf__set_traits(self, vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24, R_d_25) }, proportion_of_conductivity = function(psi) { Leaf__proportion_of_conductivity(self, psi) @@ -467,6 +467,27 @@ NULL Leaf__rd_to_vcmax_ratio___set(self, value) } }, + R_d_25 = function(value) { + if (missing(value)) { + Leaf__R_d_25__get(self) + } else { + Leaf__R_d_25__set(self, value) + } + }, + rd_q10_intercept_ = function(value) { + if (missing(value)) { + Leaf__rd_q10_intercept___get(self) + } else { + Leaf__rd_q10_intercept___set(self, value) + } + }, + rd_q10_slope_ = function(value) { + if (missing(value)) { + Leaf__rd_q10_slope___get(self) + } else { + Leaf__rd_q10_slope___set(self, value) + } + }, PPFD_ = function(value) { if (missing(value)) { Leaf__PPFD___get(self) diff --git a/R/gradient-batch.R b/R/gradient-batch.R index 1d75c52..a56177c 100644 --- a/R/gradient-batch.R +++ b/R/gradient-batch.R @@ -333,14 +333,31 @@ leaf_gradient_batch <- function(batch, # By NAME, not by position. `leaf_traits()` is in `set_traits()`'s order and # test-gradient.R asserts it, but this is the one place a silent reordering # would produce plausible numbers for the wrong parameters. - tv <- unlist(traits)[par_names[seq_len(length(par_names) - 2L)]] + # + # ⚠️ AND THE TRAITS ARE NO LONGER THE LEADING BLOCK OF `par_names`. `R_d_25` is a + # trait that the enumeration appends AFTER the two non-traits, so "all but the + # last two" reads `leaf_specific_conductance_max` as a trait -- which is how #41 + # first failed here, reporting "`traits` is missing: NA" -- where the NA was the + # NAME of a trait that does not exist, not a missing value. The names are taken + # by set difference and placed by `match()`, so + # neither end of the list is assumed contiguous. + non_traits <- c("leaf_specific_conductance_max", "resistance") + trait_names <- setdiff(par_names, non_traits) + tv <- unlist(traits)[trait_names] + # The sentinel resolved here rather than passed through: see `.resolve_rd_25()`. + # It has to happen BEFORE the anyNA() check, which would otherwise read the + # default `R_d_25` as a missing trait. + tv[["R_d_25"]] <- .resolve_rd_25(tv[["R_d_25"]], tv[["vcmax_25"]], + batch$leaf$rd_to_vcmax_ratio_) if (anyNA(tv)) { - stop("`traits` is missing: ", paste(names(tv)[is.na(tv)], collapse = ", "), - call. = FALSE) + stop("`traits` is missing: ", + paste(trait_names[is.na(tv)], collapse = ", "), call. = FALSE) } - m[, seq_along(tv)] <- rep(tv, each = nr) - m[, length(par_names) - 1L] <- batch$kmax - m[, length(par_names)] <- batch$resistance + m[, match(trait_names, par_names)] <- rep(tv, each = nr) + m[, match("leaf_specific_conductance_max", par_names)] <- batch$kmax + # NA on the multi-layer path, where there is no such parameter and C++ never + # reads the column. + m[, match("resistance", par_names)] <- batch$resistance m } diff --git a/R/gradient.R b/R/gradient.R index 4468711..91f9d8c 100644 --- a/R/gradient.R +++ b/R/gradient.R @@ -58,7 +58,7 @@ ##' `R_d_` are derived from the traits inside `set_physiology()`, so they are ##' genuinely unknown until the drivers are re-supplied. ##' -##' The reason it is a function rather than thirteen assignable fields is that +##' The reason it is a function rather than fourteen assignable fields is that ##' `leaf$vcmax_25 <- x` could not be made correct. Three separate pieces of ##' derived state go stale on a bare trait write: the two pre-integrated ##' vulnerability splines, the solved operating point, and -- least visibly -- @@ -87,10 +87,14 @@ set_traits <- function(x, traits) { } # Positional, in the C++ argument order, for the same reason leaf_model() is: # the ordering is written down once rather than at every call site. + # ⚠️ `R_d_25` is last and is usually NA -- the sentinel for "derive from + # vcmax_25". It must be passed rather than dropped: leaving it out would make a + # re-traited leaf differ from a fresh one built with the same traits, which is + # exactly the invariant test_set_traits_matches_a_fresh_leaf asserts bit-exactly. x$set_traits(traits$vcmax_25, traits$stem_c, traits$stem_b, traits$psi_crit, traits$root_c, traits$root_b, traits$root_psi_crit, traits$beta2, traits$jmax_25, traits$a, traits$curv_fact_elec_trans, - traits$curv_fact_colim, traits$cost_scale_TF24) + traits$curv_fact_colim, traits$cost_scale_TF24, traits$R_d_25) invisible(x) } @@ -202,9 +206,9 @@ set_traits <- function(x, traits) { ##' 57-parameter variant costing the same as its 40-parameter one, because ##' `P_model` is 4 in both. ##' -##' ⚠️ **Always pass `pars`.** It is `P_model`, so the default — all fourteen on +##' ⚠️ **Always pass `pars`.** It is `P_model`, so the default — all fifteen on ##' the multi-layer path — is the most expensive thing you can ask for, and a fit -##' that reads four of them pays for ten it discards. +##' that reads four of them pays for eleven it discards. ##' ##' The intercept is a fresh `Leaf` per call, which there is currently no way to ##' avoid (see phylloptim#52); it is 29% of the exact gradient in the study above. @@ -247,10 +251,22 @@ set_traits <- function(x, traits) { ##' @param control a [leaf_control()] object ##' @param supply how water reaches the root collar: [leaf_supply_multilayer()] ##' (the default) or [leaf_supply_single()] -##' @param pars what to differentiate with respect to. Any of the thirteen +##' @param pars what to differentiate with respect to. Any of the fourteen ##' [leaf_traits()] names, plus `"leaf_specific_conductance_max"` and — on the ##' single-potential path only — `"resistance"`. Defaults to all of them. ##' +##' ⚠️ The ORDER of the enumeration is not `leaf_traits()`' order: `"R_d_25"` +##' comes last, after the two non-traits, because the C++ side indexes this list +##' by position and inserting it would have moved the other two. That matters +##' only if you build `theta` yourself; `pars` itself is matched by name. +##' +##' `"R_d_25"` is differentiable at its `NA` default, which is resolved to +##' `rd_to_vcmax_ratio_ * vcmax_25` before anything is perturbed. The +##' consequence worth knowing: `dY/dvcmax_25` is then a PARTIAL at fixed +##' respiration. It used to carry the respiration term as well, because `R_d` +##' was derived from `vcmax_25` with nothing else to hold it. Add +##' `rd_to_vcmax_ratio_ * dY/dR_d_25` for the total derivative. +##' ##' `beta_R_H` and `beta_R_V` were here until #33 and are not any more: they ##' parameterise the root-architecture model, which the leaf no longer runs, so ##' this function has no way to reach them. Getting a gradient in either means @@ -387,12 +403,8 @@ leaf_gradient <- function(psi_soil, atm_vpd = atm_vpd, ca = ca, leaf_temp = leaf_temp, atm_o2_kpa = atm_o2_kpa, atm_kpa = atm_kpa) - # The differentiable parameters: the thirteen traits, plus the two that are not - # traits and that a calibration nonetheless fits (#44). See .gradient_theta. - theta <- .gradient_theta(traits, leaf_specific_conductance_max, supply, - root_network) if (is.null(pars)) { - pars <- names(theta) + pars <- .gradient_available_pars(identical(supply$kind, "single")) } # Shared with leaf_gradient_batch(), so the two entry points cannot disagree # about which parameters exist or explain a rejection differently. @@ -407,6 +419,20 @@ leaf_gradient <- function(psi_soil, # a call in a per-observation fit. Construction is the single largest term on # this surface. l <- if (is.null(x)) leaf_model(traits, control, supply) else x + + # The differentiable parameters: the thirteen traits, plus `R_d_25` and the two + # that are not traits and that a calibration nonetheless fits (#44). See + # .gradient_theta. + # + # ⚠️ AFTER the leaf, because resolving `R_d_25`'s sentinel needs + # `rd_to_vcmax_ratio_`, which is a field of the leaf and not of `traits`. Reading + # it from `l` rather than defaulting it here is what keeps the resolved value + # equal to the one `set_physiology()` would have derived, including for a caller + # who passes an `x` carrying a non-default ratio. `pars` no longer comes from + # theta's names for the same reason: it is available earlier, and + # `.gradient_available_pars()` is the same list in the same order. + theta <- .gradient_theta(traits, leaf_specific_conductance_max, supply, + root_network, l$rd_to_vcmax_ratio_) reset <- .gradient_setter(l, traits, drivers, supply, fast_stem_curve) if (is.null(x)) { @@ -577,8 +603,16 @@ leaf_gradient <- function(psi_soil, nms <- NULL function() { if (is.null(nms)) { - nms <<- c(names(.leaf_trait_defaults), "leaf_specific_conductance_max", - "resistance") + # ⚠️ `R_d_25` GOES LAST, NOT IN leaf_traits()' ORDER, and this deviation is + # forced rather than chosen. C++ appends it at index 15 because putting it in + # `set_traits`' argument order would place it at 13 and displace `par_kmax` / + # `par_resistance` -- the reorder `gradient.hpp` warns is unsafe. The two + # lists must agree position-for-position, so R follows suit. The + # C++-versus-R comparison in `test-gradient-batch.R` is what holds them + # together; drop the `setdiff` and it fails there rather than silently + # differentiating the wrong parameter. + traits <- setdiff(names(.leaf_trait_defaults), "R_d_25") + nms <<- c(traits, "leaf_specific_conductance_max", "resistance", "R_d_25") } nms } @@ -637,14 +671,67 @@ leaf_gradient <- function(psi_soil, # and `dY/dtheta = dY/dtheta|_psi + (dY/dpsi)(dpsi*/dtheta)` hold for any # parameter profit depends on. What differs per parameter is only which setter # applies it, which is .gradient_setter's job. -.gradient_theta <- function(traits, kmax, supply, root_network) { - theta <- c(unlist(traits), leaf_specific_conductance_max = kmax) +.gradient_theta <- function(traits, kmax, supply, root_network, + rd_to_vcmax_ratio) { + # ⚠️ `R_d_25` LAST, matching `.gradient_par_names()` and C++'s `par_names()`. + # `unlist(traits)` alone would put it at position 14 -- leaf_traits()' own order + # -- which is NOT the enumeration order, because C++ appends it after the two + # non-traits rather than displacing them. Getting this wrong differentiates the + # wrong parameter silently, so it is built from the canonical name list rather + # than from whatever order the traits object happens to have. + tr <- unlist(traits) + theta <- c(tr[setdiff(names(tr), "R_d_25")], + leaf_specific_conductance_max = kmax) if (identical(supply$kind, "single")) { theta <- c(theta, resistance = root_network$r_R_V_sum[[1]]) } + theta <- c(theta, R_d_25 = .resolve_rd_25(tr[["R_d_25"]], tr[["vcmax_25"]], + rd_to_vcmax_ratio)) + stopifnot("theta must be in gradient_par_names() order" = + identical(names(theta), + intersect(.gradient_par_names(), names(theta)))) theta } +# `R_d_25`'s NA sentinel, resolved to the number the model would have derived. +# +# ⚠️ THETA MUST NEVER CARRY THE SENTINEL, and two separate things say so. +# +# * It is not a value the batch path can even represent. `theta` there is a +# numeric matrix, in which an NA is indistinguishable from a trait the caller +# forgot -- which is exactly how it was first reported ("`traits` is missing: +# NA"). And `NaN == NaN` is false, so nothing downstream could compare such a +# column against anything either. +# * A parameter whose value is "derive it" is not differentiable: perturbing NA +# gives NA. Left unresolved, `R_d_25` would become a gradient parameter only +# after a caller had already pinned a finite value -- the opposite of what a +# calibration that starts from the default needs. +# +# The substitution is `rd_to_vcmax_ratio_ * vcmax_25`, which is the same +# expression `Leaf::rd_reference()` evaluates, so the base point is BIT-IDENTICAL: +# one multiply of the same two doubles either side of the boundary. The ratio is +# read off the leaf rather than defaulted here, so there is no second copy of +# 0.015 to drift from the field's own default. +# +# ⚠️ WHAT IT DOES CHANGE IS THE `vcmax_25` DERIVATIVE, and that is deliberate: with +# `R_d_25` a parameter in its own right, `dY/dvcmax_25` is a PARTIAL at fixed +# respiration, where before it carried `ratio * dY/dR_d_25` as well. That is the +# correct Jacobian column for a fit that moves both, and the total derivative is +# recovered exactly as `dY/dvcmax_25 + ratio * dY/dR_d_25`. +# +# It is the only column that moves. Measured over `gradient_golden.tsv`'s five +# operating points: 14 of 60 recorded cells changed, ALL of them `vcmax_25`, by +# between 16% and 250% -- the 250% is the five-layer row, where the two terms +# nearly cancelled, so dropping one is not a small edit. The chain rule above +# reconstructs every one of the 14 old values, exactly where both arms are exact +# and to 2.8e-04 at worst where they are not (that residual is the direct term's +# own finite-difference round-off: it falls to 2.5e-06 at `step = 1e-4`). +# `dA/dvcmax_25` at a shut-down point is the cleanest case -- exactly -0.015 +# before, exactly 0 now, with the -1 moved to `dA/dR_d_25`. +.resolve_rd_25 <- function(R_d_25, vcmax_25, rd_to_vcmax_ratio) { + if (is.na(R_d_25)) rd_to_vcmax_ratio * vcmax_25 else R_d_25 +} + # Push a parameter vector back onto the leaf, in the one order that is correct. # # ⚠️ ORDER IS LOAD-BEARING and the reason this is a function rather than three @@ -719,12 +806,22 @@ leaf_gradient <- function(psi_soil, # the #25 positive-magnitude invariants itself. Do not copy this pattern anywhere # the values are not already known-good. # ⚠️ POSITIONAL, so the count is load-bearing. `set_traits()`'s C++ signature and - # `leaf_traits()` must agree on thirteen; if a trait is ever added, this call is + # `leaf_traits()` must agree on FOURTEEN; if a trait is ever added, this call is # the one place that will not fail to compile. test-gradient.R asserts the arity. + # + # ⚠️ THAT PREDICTION CAME TRUE. Adding `R_d_25` (#41) broke here and nowhere + # else, at run time, with "argument R_d_25 is missing" from inside the generated + # binding -- a message that names neither this line nor the trait count. The + # arity assertion in test-gradient.R is what should catch the next one. + # + # `tv` is in `leaf_traits()`' order, where R_d_25 is fourteenth -- which is + # set_traits' argument order. It is NOT `.gradient_par_names()` order, in which + # R_d_25 comes after the two non-traits; `theta[trait_names]` is what reconciles + # the two. tv <- theta[trait_names] apply_traits(tv[[1L]], tv[[2L]], tv[[3L]], tv[[4L]], tv[[5L]], tv[[6L]], tv[[7L]], tv[[8L]], tv[[9L]], tv[[10L]], tv[[11L]], tv[[12L]], - tv[[13L]]) + tv[[13L]], tv[[14L]]) # `resistance` is a driver, so it goes in with the others rather than through # $set_supply_single(). That removes the second object-resetting call this # function used to make -- and with it the reason the ordering note above had to diff --git a/R/leaf-model.R b/R/leaf-model.R index 610db87..a47a1e8 100644 --- a/R/leaf-model.R +++ b/R/leaf-model.R @@ -86,6 +86,15 @@ ##' @param curv_fact_colim curvature of the colimited photosynthesis equation ##' @param cost_scale_TF24 cost parameter for the TF24 profit model ##' (umol m^-2 s^-1) +##' @param R_d_25 dark respiration at 25 C (umol m^-2 s^-1). `NA`, the default, +##' means *derive it* as `rd_to_vcmax_ratio_ * vcmax_25`, which is what the +##' model has always done; a number pins it and breaks that link. Unlike every +##' other trait it accepts `NA`, and it is the one trait the generated `Leaf` +##' constructor does not take -- [leaf_model()] assigns the field afterwards. +##' +##' Either way it is the value at 25 C only: respiration rises from there with +##' Tjoelker's declining-Q10 curve (#41), so pinning `R_d_25` fixes the +##' reference point and not the temperature response. ##' ##' @section Where the two root-resistance constants went: ##' `beta_R_H` and `beta_R_V` were traits here until #33. They parameterise the @@ -115,7 +124,8 @@ leaf_traits <- function(vcmax_25 = 96, a = 0.30, curv_fact_elec_trans = 0.7, curv_fact_colim = 0.99, - cost_scale_TF24 = 7.5) { + cost_scale_TF24 = 7.5, + R_d_25 = NA_real_) { out <- list(vcmax_25 = vcmax_25, stem_c = stem_c, stem_b = stem_b, psi_crit = psi_crit, root_c = root_c, root_b = root_b, root_psi_crit = root_psi_crit, beta2 = beta2, @@ -124,6 +134,19 @@ leaf_traits <- function(vcmax_25 = 96, curv_fact_colim = curv_fact_colim, cost_scale_TF24 = cost_scale_TF24) .check_scalars(out, "leaf_traits") + # ⚠️ `R_d_25` is checked SEPARATELY because `NA` is a legitimate value for it and + # `.check_scalars()` demands finiteness. NA means "derive as + # 0.015 * vcmax_25", i.e. the behaviour every other trait combination has always + # had; a number overrides that. Folding it into the loop above would reject the + # default. + if (!(is.numeric(R_d_25) && length(R_d_25) == 1L)) { + stop("leaf_traits(): R_d_25 must be a single number, or NA to derive it ", + "from vcmax_25", call. = FALSE) + } + if (!is.na(R_d_25) && R_d_25 < 0) { + stop("leaf_traits(): R_d_25 must be non-negative", call. = FALSE) + } + out$R_d_25 <- as.numeric(R_d_25) structure(out, class = c("leaf_traits", "list")) } @@ -365,6 +388,12 @@ leaf_model <- function(traits = leaf_traits(), control = leaf_control(), ci_niter = control$ci_niter, cost_scale_TF24 = traits$cost_scale_TF24 ) + # ⚠️ R_d_25 goes on AFTER construction, because the generated constructor does not + # take it -- and it must go on at all, or `leaf_traits(R_d_25 = 0.525)` would be + # accepted and silently ignored, which is worse than not offering the argument. + # Safe here: nothing has been solved yet, and the temperature cache keys on the + # resolved reference value, so the next set_drivers() picks it up. + l$R_d_25 <- traits$R_d_25 l$initialize_integrator(control$integration_rule, control$integration_tol) # After the integrator, because set_supply_single clears the solved state -- # not the integrator tolerance, but relying on that ordering would be a diff --git a/inst/RcppR6_classes.yml b/inst/RcppR6_classes.yml index 9012d35..611d13a 100644 --- a/inst/RcppR6_classes.yml +++ b/inst/RcppR6_classes.yml @@ -210,6 +210,20 @@ Leaf: ko_25_: {type: double, access: field} ko_ha_: {type: double, access: field} rd_to_vcmax_ratio_: {type: double, access: field} + # Dark respiration at 25 C. NA/NaN means "derive as rd_to_vcmax_ratio_ * + # vcmax_25" -- the historical behaviour -- and a number overrides it. Bound as a + # field as well as being a `set_traits()` argument, because `leaf_model()` needs + # to apply it after the generated constructor (which does not take it). + R_d_25: {type: double, access: field} + # The Tjoelker (2001) declining-Q10 coefficients: + # Q10(T) = rd_q10_intercept_ - rd_q10_slope_ * (T + 25) / 2 + # ⚠️ Set the slope to zero and the intercept IS a constant Q10, which is the + # escape hatch for anyone who wants the conventional form. A constant Q10 = 2 + # was the first implementation and was measured too aggressive at the top of the + # range: R_d 4.07 at 40 C, -73% on assimilation, and no operating point at all + # by 45 C. See NEWS for the blast radius. + rd_q10_intercept_: {type: double, access: field} + rd_q10_slope_: {type: double, access: field} # --- drivers, as last set by set_physiology ------------------------------ PPFD_: {type: double, access: field} @@ -336,7 +350,7 @@ Leaf: args: [stem_b: double] set_traits: return_type: void - args: [vcmax_25: double, stem_c: double, stem_b: double, psi_crit: double, root_c: double, root_b: double, root_psi_crit: double, beta2: double, jmax_25: double, a: double, curv_fact_elec_trans: double, curv_fact_colim: double, cost_scale_TF24: double] + args: [vcmax_25: double, stem_c: double, stem_b: double, psi_crit: double, root_c: double, root_b: double, root_psi_crit: double, beta2: double, jmax_25: double, a: double, curv_fact_elec_trans: double, curv_fact_colim: double, cost_scale_TF24: double, R_d_25: double] # --- transpiration and conductance --------------------------------------- proportion_of_conductivity: diff --git a/inst/include/phylloptim/gradient.hpp b/inst/include/phylloptim/gradient.hpp index 004f557..688c751 100644 --- a/inst/include/phylloptim/gradient.hpp +++ b/inst/include/phylloptim/gradient.hpp @@ -73,13 +73,20 @@ namespace gradient { // back out of C++ and compares them with R's, so the two cannot drift apart // without a failure. inline constexpr int n_traits = 13; -inline constexpr int n_pars = 15; +inline constexpr int n_pars = 16; -// The two indices the code below has to know by name: one takes the fast -// homogeneity path, and the two non-traits take a relative step. +// The indices the code below has to know by name: one takes the fast homogeneity +// path, and the two non-traits take a relative step. inline constexpr int par_stem_b = 2; inline constexpr int par_kmax = 13; inline constexpr int par_resistance = 14; +// ⚠️ `R_d_25` IS A TRAIT AND IS APPENDED AT THE END RATHER THAN PUT IN +// `set_traits`' ARGUMENT ORDER, WHICH WOULD PLACE IT AT 13. That would displace +// `par_kmax` and `par_resistance` -- a reorder, which the warning above says is +// exactly the unsafe move. So this enumeration and `set_traits`' argument order +// agree for the first thirteen and deliberately diverge here; `set_setter` passes +// `theta[par_R_d_25]` as that function's fourteenth argument. +inline constexpr int par_R_d_25 = 15; inline const std::vector& par_names() { static const std::vector names{ @@ -89,7 +96,8 @@ inline const std::vector& par_names() { "a", "curv_fact_elec_trans", "curv_fact_colim", "cost_scale_TF24", "leaf_specific_conductance_max", - "resistance"}; + "resistance", + "R_d_25"}; return names; } @@ -270,7 +278,7 @@ inline void apply(Leaf& l, const double* theta, const Drivers& d, bool single, } l.set_traits(theta[0], theta[1], theta[2], theta[3], theta[4], theta[5], theta[6], theta[7], theta[8], theta[9], theta[10], theta[11], - theta[12]); + theta[12], theta[par_R_d_25]); if (single) { // R's `series_resistance()`: a default-constructed network carrying one // series resistance in `r_R_V_sum`, which is that field's own meaning with diff --git a/inst/include/phylloptim/leaf_model.hpp b/inst/include/phylloptim/leaf_model.hpp index f29ed0b..673a47c 100644 --- a/inst/include/phylloptim/leaf_model.hpp +++ b/inst/include/phylloptim/leaf_model.hpp @@ -550,11 +550,15 @@ class Leaf { // resets both caches and requires set_physiology() before the next solve, exactly // as a fresh Leaf would. That last part is not conservatism: the derived // photosynthetic parameters really are unknown until the drivers are re-supplied. + // ⚠️ `R_d_25` is LAST and may be NaN, which is a value rather than an error -- + // the sentinel meaning "derive from rd_to_vcmax_ratio_ * vcmax_25". So it is + // deliberately outside check_psi_magnitudes' remit and must not be validated as + // finite. void set_traits(double vcmax_25, double stem_c, double stem_b, double psi_crit, double root_c, double root_b, double root_psi_crit, double beta2, double jmax_25, double a, double curv_fact_elec_trans, double curv_fact_colim, - double cost_scale_TF24); + double cost_scale_TF24, double R_d_25); // The #25 boundary: the four potentials that must be positive magnitudes. One // copy, called from both the constructor and set_traits -- the alternative is @@ -1224,7 +1228,7 @@ inline void Leaf::set_traits(double vcmax_25_, double stem_c_, double stem_b_, double jmax_25_, double a_, double curv_fact_elec_trans_, double curv_fact_colim_, - double cost_scale_TF24_) { + double cost_scale_TF24_, double R_d_25_) { check_psi_magnitudes(psi_crit_, stem_b_, root_b_, root_psi_crit_); // Which splines have to be rebuilt, decided BEFORE the assignment. Exact @@ -1253,6 +1257,9 @@ inline void Leaf::set_traits(double vcmax_25_, double stem_c_, double stem_b_, curv_fact_elec_trans = curv_fact_elec_trans_; curv_fact_colim = curv_fact_colim_; cost_scale_TF24 = cost_scale_TF24_; + // NaN is a legitimate value here, so this is a plain assignment: it restores the + // "derive from the ratio" default as readily as it sets a measured value. + R_d_25 = R_d_25_; roots_.root_c = root_c_; roots_.root_b = root_b_; diff --git a/man/leaf_gradient.Rd b/man/leaf_gradient.Rd index 1e88746..54818fe 100644 --- a/man/leaf_gradient.Rd +++ b/man/leaf_gradient.Rd @@ -70,10 +70,22 @@ differentiate at} \item{supply}{how water reaches the root collar: [leaf_supply_multilayer()] (the default) or [leaf_supply_single()]} -\item{pars}{what to differentiate with respect to. Any of the thirteen +\item{pars}{what to differentiate with respect to. Any of the fourteen [leaf_traits()] names, plus `"leaf_specific_conductance_max"` and — on the single-potential path only — `"resistance"`. Defaults to all of them. + ⚠️ The ORDER of the enumeration is not `leaf_traits()`' order: `"R_d_25"` + comes last, after the two non-traits, because the C++ side indexes this list + by position and inserting it would have moved the other two. That matters + only if you build `theta` yourself; `pars` itself is matched by name. + + `"R_d_25"` is differentiable at its `NA` default, which is resolved to + `rd_to_vcmax_ratio_ * vcmax_25` before anything is perturbed. The + consequence worth knowing: `dY/dvcmax_25` is then a PARTIAL at fixed + respiration. It used to carry the respiration term as well, because `R_d` + was derived from `vcmax_25` with nothing else to hold it. Add + `rd_to_vcmax_ratio_ * dY/dR_d_25` for the total derivative. + `beta_R_H` and `beta_R_V` were here until #33 and are not any more: they parameterise the root-architecture model, which the leaf no longer runs, so this function has no way to reach them. Getting a gradient in either means @@ -236,9 +248,9 @@ The companion study `leaf-calibration` has `N = 1327`, `P_fit = 40`, 57-parameter variant costing the same as its 40-parameter one, because `P_model` is 4 in both. -⚠️ **Always pass `pars`.** It is `P_model`, so the default — all fourteen on +⚠️ **Always pass `pars`.** It is `P_model`, so the default — all fifteen on the multi-layer path — is the most expensive thing you can ask for, and a fit -that reads four of them pays for ten it discards. +that reads four of them pays for eleven it discards. The intercept is a fresh `Leaf` per call, which there is currently no way to avoid (see phylloptim#52); it is 29% of the exact gradient in the study above. diff --git a/man/leaf_traits.Rd b/man/leaf_traits.Rd index 1207382..b6adf53 100644 --- a/man/leaf_traits.Rd +++ b/man/leaf_traits.Rd @@ -17,7 +17,8 @@ leaf_traits( a = 0.3, curv_fact_elec_trans = 0.7, curv_fact_colim = 0.99, - cost_scale_TF24 = 7.5 + cost_scale_TF24 = 7.5, + R_d_25 = NA_real_ ) } \arguments{ @@ -47,6 +48,16 @@ leaf_traits( \item{cost_scale_TF24}{cost parameter for the TF24 profit model (umol m^-2 s^-1)} + +\item{R_d_25}{dark respiration at 25 C (umol m^-2 s^-1). `NA`, the default, + means *derive it* as `rd_to_vcmax_ratio_ * vcmax_25`, which is what the + model has always done; a number pins it and breaks that link. Unlike every + other trait it accepts `NA`, and it is the one trait the generated `Leaf` + constructor does not take -- [leaf_model()] assigns the field afterwards. + + Either way it is the value at 25 C only: respiration rises from there with + Tjoelker's declining-Q10 curve (#41), so pinning `R_d_25` fixes the + reference point and not the temperature response.} } \value{ A `leaf_traits` object; a named list. diff --git a/man/set_traits.Rd b/man/set_traits.Rd index 5d1ea42..6dd2ccd 100644 --- a/man/set_traits.Rd +++ b/man/set_traits.Rd @@ -27,7 +27,7 @@ be called before the next solve. That is not caution: `vcmax_`, `jmax_` and `R_d_` are derived from the traits inside `set_physiology()`, so they are genuinely unknown until the drivers are re-supplied. -The reason it is a function rather than thirteen assignable fields is that +The reason it is a function rather than fourteen assignable fields is that `leaf$vcmax_25 <- x` could not be made correct. Three separate pieces of derived state go stale on a bare trait write: the two pre-integrated vulnerability splines, the solved operating point, and -- least visibly -- diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 81298b7..ba5d395 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -103,8 +103,8 @@ BEGIN_RCPP END_RCPP } // Leaf__set_traits -void Leaf__set_traits(phylloptim::RcppR6::RcppR6 obj_, double vcmax_25, double stem_c, double stem_b, double psi_crit, double root_c, double root_b, double root_psi_crit, double beta2, double jmax_25, double a, double curv_fact_elec_trans, double curv_fact_colim, double cost_scale_TF24); -RcppExport SEXP _phylloptim_Leaf__set_traits(SEXP obj_SEXP, SEXP vcmax_25SEXP, SEXP stem_cSEXP, SEXP stem_bSEXP, SEXP psi_critSEXP, SEXP root_cSEXP, SEXP root_bSEXP, SEXP root_psi_critSEXP, SEXP beta2SEXP, SEXP jmax_25SEXP, SEXP aSEXP, SEXP curv_fact_elec_transSEXP, SEXP curv_fact_colimSEXP, SEXP cost_scale_TF24SEXP) { +void Leaf__set_traits(phylloptim::RcppR6::RcppR6 obj_, double vcmax_25, double stem_c, double stem_b, double psi_crit, double root_c, double root_b, double root_psi_crit, double beta2, double jmax_25, double a, double curv_fact_elec_trans, double curv_fact_colim, double cost_scale_TF24, double R_d_25); +RcppExport SEXP _phylloptim_Leaf__set_traits(SEXP obj_SEXP, SEXP vcmax_25SEXP, SEXP stem_cSEXP, SEXP stem_bSEXP, SEXP psi_critSEXP, SEXP root_cSEXP, SEXP root_bSEXP, SEXP root_psi_critSEXP, SEXP beta2SEXP, SEXP jmax_25SEXP, SEXP aSEXP, SEXP curv_fact_elec_transSEXP, SEXP curv_fact_colimSEXP, SEXP cost_scale_TF24SEXP, SEXP R_d_25SEXP) { BEGIN_RCPP Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); @@ -121,7 +121,8 @@ BEGIN_RCPP Rcpp::traits::input_parameter< double >::type curv_fact_elec_trans(curv_fact_elec_transSEXP); Rcpp::traits::input_parameter< double >::type curv_fact_colim(curv_fact_colimSEXP); Rcpp::traits::input_parameter< double >::type cost_scale_TF24(cost_scale_TF24SEXP); - Leaf__set_traits(obj_, vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24); + Rcpp::traits::input_parameter< double >::type R_d_25(R_d_25SEXP); + Leaf__set_traits(obj_, vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24, R_d_25); return R_NilValue; END_RCPP } @@ -1350,6 +1351,72 @@ BEGIN_RCPP return R_NilValue; END_RCPP } +// Leaf__R_d_25__get +double Leaf__R_d_25__get(phylloptim::RcppR6::RcppR6 obj_); +RcppExport SEXP _phylloptim_Leaf__R_d_25__get(SEXP obj_SEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); + rcpp_result_gen = Rcpp::wrap(Leaf__R_d_25__get(obj_)); + return rcpp_result_gen; +END_RCPP +} +// Leaf__R_d_25__set +void Leaf__R_d_25__set(phylloptim::RcppR6::RcppR6 obj_, double value); +RcppExport SEXP _phylloptim_Leaf__R_d_25__set(SEXP obj_SEXP, SEXP valueSEXP) { +BEGIN_RCPP + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); + Rcpp::traits::input_parameter< double >::type value(valueSEXP); + Leaf__R_d_25__set(obj_, value); + return R_NilValue; +END_RCPP +} +// Leaf__rd_q10_intercept___get +double Leaf__rd_q10_intercept___get(phylloptim::RcppR6::RcppR6 obj_); +RcppExport SEXP _phylloptim_Leaf__rd_q10_intercept___get(SEXP obj_SEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); + rcpp_result_gen = Rcpp::wrap(Leaf__rd_q10_intercept___get(obj_)); + return rcpp_result_gen; +END_RCPP +} +// Leaf__rd_q10_intercept___set +void Leaf__rd_q10_intercept___set(phylloptim::RcppR6::RcppR6 obj_, double value); +RcppExport SEXP _phylloptim_Leaf__rd_q10_intercept___set(SEXP obj_SEXP, SEXP valueSEXP) { +BEGIN_RCPP + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); + Rcpp::traits::input_parameter< double >::type value(valueSEXP); + Leaf__rd_q10_intercept___set(obj_, value); + return R_NilValue; +END_RCPP +} +// Leaf__rd_q10_slope___get +double Leaf__rd_q10_slope___get(phylloptim::RcppR6::RcppR6 obj_); +RcppExport SEXP _phylloptim_Leaf__rd_q10_slope___get(SEXP obj_SEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); + rcpp_result_gen = Rcpp::wrap(Leaf__rd_q10_slope___get(obj_)); + return rcpp_result_gen; +END_RCPP +} +// Leaf__rd_q10_slope___set +void Leaf__rd_q10_slope___set(phylloptim::RcppR6::RcppR6 obj_, double value); +RcppExport SEXP _phylloptim_Leaf__rd_q10_slope___set(SEXP obj_SEXP, SEXP valueSEXP) { +BEGIN_RCPP + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); + Rcpp::traits::input_parameter< double >::type value(valueSEXP); + Leaf__rd_q10_slope___set(obj_, value); + return R_NilValue; +END_RCPP +} // Leaf__PPFD___get double Leaf__PPFD___get(phylloptim::RcppR6::RcppR6 obj_); RcppExport SEXP _phylloptim_Leaf__PPFD___get(SEXP obj_SEXP) { @@ -2199,7 +2266,7 @@ static const R_CallMethodDef CallEntries[] = { {"_phylloptim_Leaf__initialize_integrator", (DL_FUNC) &_phylloptim_Leaf__initialize_integrator, 3}, {"_phylloptim_Leaf__set_physiology", (DL_FUNC) &_phylloptim_Leaf__set_physiology, 11}, {"_phylloptim_Leaf__perturb_stem_b", (DL_FUNC) &_phylloptim_Leaf__perturb_stem_b, 2}, - {"_phylloptim_Leaf__set_traits", (DL_FUNC) &_phylloptim_Leaf__set_traits, 14}, + {"_phylloptim_Leaf__set_traits", (DL_FUNC) &_phylloptim_Leaf__set_traits, 15}, {"_phylloptim_Leaf__proportion_of_conductivity", (DL_FUNC) &_phylloptim_Leaf__proportion_of_conductivity, 2}, {"_phylloptim_Leaf__arrh_curve", (DL_FUNC) &_phylloptim_Leaf__arrh_curve, 4}, {"_phylloptim_Leaf__peak_arrh_curve", (DL_FUNC) &_phylloptim_Leaf__peak_arrh_curve, 6}, @@ -2308,6 +2375,12 @@ static const R_CallMethodDef CallEntries[] = { {"_phylloptim_Leaf__ko_ha___set", (DL_FUNC) &_phylloptim_Leaf__ko_ha___set, 2}, {"_phylloptim_Leaf__rd_to_vcmax_ratio___get", (DL_FUNC) &_phylloptim_Leaf__rd_to_vcmax_ratio___get, 1}, {"_phylloptim_Leaf__rd_to_vcmax_ratio___set", (DL_FUNC) &_phylloptim_Leaf__rd_to_vcmax_ratio___set, 2}, + {"_phylloptim_Leaf__R_d_25__get", (DL_FUNC) &_phylloptim_Leaf__R_d_25__get, 1}, + {"_phylloptim_Leaf__R_d_25__set", (DL_FUNC) &_phylloptim_Leaf__R_d_25__set, 2}, + {"_phylloptim_Leaf__rd_q10_intercept___get", (DL_FUNC) &_phylloptim_Leaf__rd_q10_intercept___get, 1}, + {"_phylloptim_Leaf__rd_q10_intercept___set", (DL_FUNC) &_phylloptim_Leaf__rd_q10_intercept___set, 2}, + {"_phylloptim_Leaf__rd_q10_slope___get", (DL_FUNC) &_phylloptim_Leaf__rd_q10_slope___get, 1}, + {"_phylloptim_Leaf__rd_q10_slope___set", (DL_FUNC) &_phylloptim_Leaf__rd_q10_slope___set, 2}, {"_phylloptim_Leaf__PPFD___get", (DL_FUNC) &_phylloptim_Leaf__PPFD___get, 1}, {"_phylloptim_Leaf__PPFD___set", (DL_FUNC) &_phylloptim_Leaf__PPFD___set, 2}, {"_phylloptim_Leaf__atm_vpd___get", (DL_FUNC) &_phylloptim_Leaf__atm_vpd___get, 1}, diff --git a/src/RcppR6.cpp b/src/RcppR6.cpp index fa1d0db..1315f2d 100644 --- a/src/RcppR6.cpp +++ b/src/RcppR6.cpp @@ -28,8 +28,8 @@ void Leaf__perturb_stem_b(phylloptim::RcppR6::RcppR6 obj_, dou obj_->perturb_stem_b(stem_b); } // [[Rcpp::export]] -void Leaf__set_traits(phylloptim::RcppR6::RcppR6 obj_, double vcmax_25, double stem_c, double stem_b, double psi_crit, double root_c, double root_b, double root_psi_crit, double beta2, double jmax_25, double a, double curv_fact_elec_trans, double curv_fact_colim, double cost_scale_TF24) { - obj_->set_traits(vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24); +void Leaf__set_traits(phylloptim::RcppR6::RcppR6 obj_, double vcmax_25, double stem_c, double stem_b, double psi_crit, double root_c, double root_b, double root_psi_crit, double beta2, double jmax_25, double a, double curv_fact_elec_trans, double curv_fact_colim, double cost_scale_TF24, double R_d_25) { + obj_->set_traits(vcmax_25, stem_c, stem_b, psi_crit, root_c, root_b, root_psi_crit, beta2, jmax_25, a, curv_fact_elec_trans, curv_fact_colim, cost_scale_TF24, R_d_25); } // [[Rcpp::export]] double Leaf__proportion_of_conductivity(phylloptim::RcppR6::RcppR6 obj_, double psi) { @@ -500,6 +500,33 @@ void Leaf__rd_to_vcmax_ratio___set(phylloptim::RcppR6::RcppR6 obj_->rd_to_vcmax_ratio_ = value; } +// [[Rcpp::export]] +double Leaf__R_d_25__get(phylloptim::RcppR6::RcppR6 obj_) { + return obj_->R_d_25; +} +// [[Rcpp::export]] +void Leaf__R_d_25__set(phylloptim::RcppR6::RcppR6 obj_, double value) { + obj_->R_d_25 = value; +} + +// [[Rcpp::export]] +double Leaf__rd_q10_intercept___get(phylloptim::RcppR6::RcppR6 obj_) { + return obj_->rd_q10_intercept_; +} +// [[Rcpp::export]] +void Leaf__rd_q10_intercept___set(phylloptim::RcppR6::RcppR6 obj_, double value) { + obj_->rd_q10_intercept_ = value; +} + +// [[Rcpp::export]] +double Leaf__rd_q10_slope___get(phylloptim::RcppR6::RcppR6 obj_) { + return obj_->rd_q10_slope_; +} +// [[Rcpp::export]] +void Leaf__rd_q10_slope___set(phylloptim::RcppR6::RcppR6 obj_, double value) { + obj_->rd_q10_slope_ = value; +} + // [[Rcpp::export]] double Leaf__PPFD___get(phylloptim::RcppR6::RcppR6 obj_) { return obj_->PPFD_; diff --git a/tests/cpp/bench_gradient.cpp b/tests/cpp/bench_gradient.cpp index 641a692..4c1f3b5 100644 --- a/tests/cpp/bench_gradient.cpp +++ b/tests/cpp/bench_gradient.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -81,8 +82,11 @@ bool rebuilds_a_spline(int i) { } void apply_traits(phylloptim::Leaf &l, const Traits &t) { + // NaN for R_d_25: the sentinel meaning "derive from the ratio", so the benchmark + // keeps measuring the default configuration rather than a fixed respiration. l.set_traits(t.v[0], t.v[1], t.v[2], t.v[3], t.v[4], t.v[5], t.v[6], t.v[7], - t.v[8], t.v[9], t.v[10], t.v[11], t.v[12]); + t.v[8], t.v[9], t.v[10], t.v[11], t.v[12], + std::numeric_limits::quiet_NaN()); } // One interior operating point. Drivers from plant's tests/testthat/test-leaf.r, diff --git a/tests/cpp/test_leaf.cpp b/tests/cpp/test_leaf.cpp index 19d00ba..24a7641 100644 --- a/tests/cpp/test_leaf.cpp +++ b/tests/cpp/test_leaf.cpp @@ -61,6 +61,12 @@ struct Drivers { double area_leaf = 0.05; }; +// set_traits' fourteenth argument, R_d_25. NaN is the SENTINEL for "derive as +// rd_to_vcmax_ratio_ * vcmax_25", so passing it keeps a call at the default +// respiration rather than pinning one -- which is what every call below wants +// except the tests that are specifically about R_d. +const double kRdDefault = std::numeric_limits::quiet_NaN(); + phylloptim::Leaf make_leaf(const Drivers &d, std::vector psi_soil, std::vector soil_depth) { phylloptim::Leaf l; @@ -857,7 +863,8 @@ void test_operating_point_kind_is_written_by_every_path() { // classification is part of that state (hazard 10 / setup_clean_leaf). l.set_traits(l.vcmax_25, l.stem_c, l.stem_b, l.psi_crit, l.roots_.root_c, l.roots_.root_b, l.roots_.root_psi_crit, l.beta2, l.jmax_25, l.a, - l.curv_fact_elec_trans, l.curv_fact_colim, l.cost_scale_TF24); + l.curv_fact_elec_trans, l.curv_fact_colim, l.cost_scale_TF24, + l.R_d_25); ok(l.operating_point_kind() == Kind::Unsolved, "set_traits clears the classification with the rest of the solved state"); @@ -2211,7 +2218,12 @@ void test_rd_temperature_response() { // Recorded as a measured limit rather than avoided by choosing a cooler sweep: // the temperature at which the model stops having an operating point is exactly // what a caller needs to know, and it moved. - printf(" blast radius on assimilation (old form vs Q10 = 2):\n"); + // ⚠️ THE LABEL BELOW SAID "Q10 = 2" AND THAT WAS STALE. A constant Q10 of 2 was + // the first implementation and was rejected on measurement (R_d 4.07 and -73% on + // A at 40 C, no operating point at all by 45 C); the "now" arm here is the + // shipped Tjoelker declining curve, which is what the numbers below describe. + // A printed label is not asserted by anything, so it outlived the thing it named. + printf(" blast radius on assimilation (old form vs declining Q10):\n"); for (double T : {15.0, 25.0, 35.0, 40.0, 45.0}) { double A_now = 0.0, Rd_now = 0.0; bool now_ok = true; @@ -2334,7 +2346,7 @@ void test_perturb_stem_b_matches_a_rebuild() { phylloptim::Leaf rebuilt = make_leaf(d, {2.0}, {1.0}); rebuilt.find_root_collar_psi(); rebuilt.set_traits(96.0, 2.680147, b_new, 5.870283, 2.680147, 3.898245, - 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5); + 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRdDefault); rebuilt.set_physiology(fixture::root_network(mrp, depth), d.PPFD, psi_soil, depth, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); @@ -2367,7 +2379,7 @@ void test_perturb_stem_b_matches_a_rebuild() { phylloptim::Leaf fresh = make_leaf(d, {2.0}, {1.0}); fresh.find_root_collar_psi(); rescaled.set_traits(96.0, 2.680147, 3.898245, 5.870283, 2.680147, 3.898245, - 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5); + 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRdDefault); rescaled.set_physiology(fixture::root_network(mrp, depth), d.PPFD, psi_soil, depth, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); @@ -2416,7 +2428,7 @@ void test_set_traits_matches_a_fresh_leaf() { phylloptim::Leaf reused = make_leaf(d, {2.0}, {1.0}); reused.find_root_collar_psi(); reused.set_traits(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], - t[10], t[11], t[12]); + t[10], t[11], t[12], kRdDefault); reused.set_physiology(fixture::root_network(mrp, depth), d.PPFD, psi_soil, depth, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); reused.find_root_collar_psi(); @@ -2446,7 +2458,7 @@ void test_set_traits_matches_a_fresh_leaf() { phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); const double vcmax_before = l.vcmax_; l.set_traits(96.0 * 2.0, 2.680147, 3.898245, 5.870283, 2.680147, 3.898245, - 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5); + 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRdDefault); std::vector mrp{1.0 / d.area_leaf}, psi_soil{2.0}, depth{1.0}; // The SAME leaf_temp and atm_o2_kpa, which is what arms the cache. l.set_physiology(fixture::root_network(mrp, depth), d.PPFD, psi_soil, depth, d.K_s * d.theta / d.h, @@ -2463,7 +2475,7 @@ void test_set_traits_matches_a_fresh_leaf() { phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); const double E_before = l.transpiration(3.0, 1.0); l.set_traits(96.0, 2.680147, 3.898245 * 1.5, 5.870283, 2.680147, 3.898245, - 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5); + 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRdDefault); std::vector mrp{1.0 / d.area_leaf}, psi_soil{2.0}, depth{1.0}; l.set_physiology(fixture::root_network(mrp, depth), d.PPFD, psi_soil, depth, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); @@ -2491,7 +2503,7 @@ void test_set_traits_matches_a_fresh_leaf() { bool threw = false; try { l.set_traits(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], - t[10], t[11], t[12]); + t[10], t[11], t[12], kRdDefault); } catch (const std::runtime_error &) { threw = true; } diff --git a/tests/testthat/gradient_golden.tsv b/tests/testthat/gradient_golden.tsv index ba54790..bc5db9d 100644 --- a/tests/testthat/gradient_golden.tsv +++ b/tests/testthat/gradient_golden.tsv @@ -1,16 +1,21 @@ case status method par A gc psi_stem collar -interior-1layer interior ift vcmax_25 0x1.19f24c79f383p-6 0x1.3259b788b7cd8p-15 0x1.06a759124089ep-8 0x1.c9aa56f8160ap-10 +interior-1layer interior ift vcmax_25 0x1.56ff4d6eecf96p-6 0x1.6279997564ff5p-15 0x1.2fe9f734f59d8p-8 0x1.08c7ad051fb7dp-9 interior-1layer interior ift stem_b 0x1.6c5b48adf2fp+1 0x1.7ab19a189bb21p-7 0x1.d9c2457829579p-1 0x1.1add81b8d5d2fp-1 interior-1layer interior ift psi_crit 0x0p+0 0x0p+0 0x0p+0 0x0p+0 -interior-5layer interior ift vcmax_25 0x1.562cd013972cdp-5 0x1.1f2719b2a9b2p-17 0x1.7b34095a49116p-12 0x1.d034f56d422fcp-13 +interior-1layer interior ift R_d_25 -0x1.fd6a09155bf1cp-3 -0x1.90ddd402a632ep-12 -0x1.57b035f654ff8p-5 -0x1.2b6ec9ddabc73p-6 +interior-5layer interior ift vcmax_25 0x1.a789fd22240c2p-5 0x1.f668e2d6ae349p-16 0x1.4bbb591c8bbecp-10 0x1.9618142da1224p-11 interior-5layer interior ift stem_b 0x1.bf615f57bdaf1p+0 0x1.40cec78217423p-6 0x1.35865423734e6p-1 0x1.03506a09d13edp-1 interior-5layer interior ift psi_crit 0x0p+0 0x0p+0 0x0p+0 0x0p+0 -pinned-dry-3layer pinned fd vcmax_25 0x1.d65f7a06148aap-7 0x0p+0 0x0p+0 0x0p+0 +interior-5layer interior ift R_d_25 -0x1.53043af91afd9p-1 -0x1.75c8e3e4fefbp-10 -0x1.ed9b3452956e1p-5 -0x1.2e209f7e6b335p-5 +pinned-dry-3layer pinned fd vcmax_25 0x1.1f8090c0306p-6 0x0p+0 0x0p+0 0x0p+0 pinned-dry-3layer pinned fd stem_b 0x1.2ccb4ca42ff14p+2 0x1.64b64bdad4946p-6 0x1.33ff011ff4998p-14 0x1.c3ef65a37fee1p-2 pinned-dry-3layer pinned fd psi_crit 0x1.41dade66b0dcp+0 0x1.7db02a11ba0cbp-8 0x1.fff9995bb6188p-1 0x1.e3a34a2bcbb21p-4 -shutdown-1layer no-gradient fd vcmax_25 -0x1.eb851eb7cb5p-7 0x0p+0 0x0p+0 0x0p+0 +pinned-dry-3layer pinned fd R_d_25 -0x1.b3f6e43dfed39p-3 0x0p+0 0x0p+0 0x0p+0 +shutdown-1layer no-gradient fd vcmax_25 0x0p+0 0x0p+0 0x0p+0 0x0p+0 shutdown-1layer no-gradient fd stem_b 0x0p+0 0x0p+0 0x0p+0 0x0p+0 shutdown-1layer no-gradient fd psi_crit 0x0p+0 0x0p+0 0x1.000000001aa4dp+0 0x1.000000001aa4dp+0 -single-potential interior ift vcmax_25 0x1.1e8d0cc6a7624p-12 0x1.46b9a3f216e9ap-21 0x1.c5e7ef6149ddep-13 0x1.a4ed700e9cb7ep-13 +shutdown-1layer no-gradient fd R_d_25 -0x1.ffffffff73c8bp-1 0x0p+0 0x0p+0 0x0p+0 +single-potential interior ift vcmax_25 0x1.8dbb95a5a7daap-11 0x1.8665f5c42e12fp-20 0x1.0f2ea755b7941p-11 0x1.f6f5831d8118cp-12 single-potential interior ift leaf_specific_conductance_max 0x1.61e2e05d142cfp+11 0x1.116a882643229p+3 0x1.c7141229c1e05p+10 0x1.603f57174c2c4p+11 single-potential interior ift resistance -0x1.f8de9025064bep-14 -0x1.861138fe7344ap-22 -0x1.34162dac5854ep-14 -0x1.0ed249f513811p-14 +single-potential interior ift R_d_25 -0x1.090f44c09b126p-5 -0x1.d8fdb4470b455p-15 -0x1.488db9f00ccp-6 -0x1.30aebd98fd4a3p-6 diff --git a/tests/testthat/test-gradient-batch.R b/tests/testthat/test-gradient-batch.R index 06508b6..795b82a 100644 --- a/tests/testthat/test-gradient-batch.R +++ b/tests/testthat/test-gradient-batch.R @@ -81,13 +81,23 @@ test_that("the parameter enumeration is the same order in R and in C++", { # integer positions into C++'s `phylloptim::gradient::par_names`, so appending # is safe and reordering would differentiate the wrong parameter and report # plausible numbers for it. Compared rather than trusted, in both directions. - r_side <- c(names(leaf_traits()), "leaf_specific_conductance_max", - "resistance") + # + # ⚠️ AND THE ENUMERATION IS NOT `leaf_traits()`' ORDER ANY MORE. `R_d_25` is a + # trait -- `set_traits()`' fourteenth argument -- but the enumeration APPENDS it + # after the two non-traits, because slotting it in at 13 would have displaced + # `par_kmax` and `par_resistance`, which is the reorder this comment warns about. + # So the two lists agree on the first thirteen and then deliberately diverge, and + # THAT is what is asserted: appending is the safe move and is what happened. + traits <- names(leaf_traits()) + r_side <- c(setdiff(traits, "R_d_25"), "leaf_specific_conductance_max", + "resistance", "R_d_25") expect_identical(gradient_par_names(), r_side) # And the count, which is what a positional trait call would silently break: - # thirteen traits then the two that are not traits. - expect_length(gradient_par_names(), 15L) - expect_identical(gradient_par_names()[1:13], names(leaf_traits())) + # thirteen traits, the two that are not traits, then R_d_25. + expect_length(gradient_par_names(), 16L) + expect_identical(gradient_par_names()[1:13], traits[1:13]) + expect_identical(gradient_par_names()[[16]], "R_d_25") + expect_identical(traits[[14]], "R_d_25") }) test_that("the batch reproduces leaf_gradient() bit-for-bit across the grid", { @@ -187,21 +197,21 @@ test_that("the recorded gradients have not moved", { # back one ULP out (#13). gold <- utils::read.delim(test_path("gradient_golden.tsv"), stringsAsFactors = FALSE) + pars_grid <- c("vcmax_25", "stem_b", "psi_crit", "R_d_25") cases <- list( - "interior-1layer" = list(args = batch_drivers(2.0), - pars = c("vcmax_25", "stem_b", "psi_crit")), + "interior-1layer" = list(args = batch_drivers(2.0), pars = pars_grid), "interior-5layer" = list(args = batch_drivers(0.5, vpd = 0.5, layers = 5L), - pars = c("vcmax_25", "stem_b", "psi_crit")), + pars = pars_grid), "pinned-dry-3layer" = list(args = batch_drivers(4.0, vpd = 0.5, layers = 3L), - pars = c("vcmax_25", "stem_b", "psi_crit")), - "shutdown-1layer" = list(args = batch_drivers(6.0), - pars = c("vcmax_25", "stem_b", "psi_crit")), + pars = pars_grid), + "shutdown-1layer" = list(args = batch_drivers(6.0), pars = pars_grid), "single-potential" = list( args = list(psi_soil = 1.5, PPFD = 900, atm_vpd = 2.0, supply = leaf_supply_single(), root_network = series_resistance(1e4)), - pars = c("vcmax_25", "leaf_specific_conductance_max", "resistance"))) + pars = c("vcmax_25", "leaf_specific_conductance_max", "resistance", + "R_d_25"))) expect_setequal(unique(gold$case), names(cases)) # ⚠️ BIT-EXACT ONLY ON THE PLATFORM THAT GENERATED IT, macOS/arm64, exactly as @@ -332,9 +342,19 @@ test_that("per-observation theta differentiates each row at its own parameters", }) b <- leaf_batch(psi_soil = psv, PPFD = 900) + # ⚠️ `R_d_25` LAST, and RESOLVED rather than left as its NA sentinel. A caller + # who builds `theta` themselves takes on the job `.gradient_theta_matrix()` does, + # and the contract is that theta holds the value the solve will USE: an NA there + # would leave each row's respiration derived from its own `vcmax_25`, so these + # rows would be differentiated at a different point than the `leaf_gradient()` + # references below -- which resolve it -- and the two would disagree by the + # respiration term rather than fail. The ratio comes off the leaf so there is no + # second copy of 0.015 in the tests either. + ratio <- b$leaf$rd_to_vcmax_ratio_ theta <- t(vapply(traits, function(tr) { - unname(c(unlist(tr)[gradient_par_names()[1:13]], 3.14e-5, NA_real_)) - }, numeric(15))) + unname(c(unlist(tr)[gradient_par_names()[1:13]], 3.14e-5, NA_real_, + ratio * tr$vcmax_25)) + }, numeric(16))) g <- leaf_gradient_batch(b, theta = theta, pars = pars) for (i in seq_along(psv)) { @@ -510,11 +530,11 @@ test_that("leaf_gradient_batch() rejects what it cannot do", { # `traits` and `theta` both say where the gradient is taken, so passing both is # refused rather than resolved in favour of one of them. - th <- matrix(1, nrow = 1, ncol = 15) + th <- matrix(1, nrow = 1, ncol = 16) expect_error(leaf_gradient_batch(b, traits = leaf_traits(), theta = th), "pass one") - expect_error(leaf_gradient_batch(b, theta = matrix(1, 1, 14)), "15 columns") - expect_error(leaf_gradient_batch(b, theta = matrix(1, 3, 15)), + expect_error(leaf_gradient_batch(b, theta = matrix(1, 1, 15)), "16 columns") + expect_error(leaf_gradient_batch(b, theta = matrix(1, 3, 16)), "1 row or one per observation") expect_error(leaf_gradient_batch(b, theta = as.data.frame(th)), "numeric matrix") diff --git a/tests/testthat/test-gradient.R b/tests/testthat/test-gradient.R index 7b5d264..7496260 100644 --- a/tests/testthat/test-gradient.R +++ b/tests/testthat/test-gradient.R @@ -167,10 +167,21 @@ test_that("a pinned optimum takes the fallback, and the composite would be wrong # a factor of 1.6 out for vcmax_25 there rather than seven orders, so a test # that only looked at the wet rows would let a threshold drift past it. dry <- grid_gradient(4, vpd = 0.5, layers = 3L, - pars = c("stem_b", "vcmax_25")) + pars = c("stem_b", "vcmax_25", "R_d_25")) expect_identical(dry$status, "pinned") - expect_equal(dry$gradient["vcmax_25", "A"], 0.014357, tolerance = 1e-3) + expect_equal(dry$gradient["vcmax_25", "A"], 0.017548, tolerance = 1e-3) expect_equal(dry$gradient["stem_b", "A"], 4.6991, tolerance = 1e-3) + + # ⚠️ THE `vcmax_25` NUMBER ABOVE WAS 0.014357 UNTIL #41, and the difference is + # not a change in the model -- it is which derivative the column reports. + # `R_d_25` is a parameter now, so `dA/dvcmax_25` is a PARTIAL at fixed + # respiration where it used to carry `ratio * dA/dR_d_25` too. Asserted as an + # identity rather than left as two unrelated recorded numbers, because that is + # what says the two columns still add up to the old one. + ratio <- leaf_model()$rd_to_vcmax_ratio_ + expect_equal(dry$gradient["vcmax_25", "A"] + + ratio * dry$gradient["R_d_25", "A"], + 0.014357, tolerance = 1e-3) }) test_that("at a pinned optimum the BOUND's own trait carries the gradient", { @@ -206,12 +217,29 @@ test_that("a shut-down operating point reports no gradient and still differences # psi_soil = 6 is drier than psi_crit, so there is no optimisation to # differentiate: dprofit returns a sentinel zero rather than a derivative, and # H comes back zero with it. The composite has nothing to stand on and says so - # -- but the gradient itself is not zero, because R_d still depends on - # vcmax_25, so the fallback still has work to do. - g <- grid_gradient(6.0, pars = c("vcmax_25", "stem_b")) + # -- but the gradient itself is not all zero, because a shut-down leaf still + # respires, so the fallback still has work to do. + # + # ⚠️ WHICH PARAMETER CARRIES THAT IS THE SHARPEST TEST OF #41 IN THE SUITE, and + # it changed there. A = -R_d exactly at a shut-down point, so: + # + # before R_d was derived from vcmax_25, so dA/dvcmax_25 = -ratio = -0.015 + # and there was no R_d_25 column at all; + # now R_d_25 is a parameter, so dA/dR_d_25 = -1 and dA/dvcmax_25 = 0. + # + # The zero is EXACT and asserted as such: `vcmax_25` no longer reaches A here at + # all, so both perturbed solves return the same bits and their difference is a + # true zero rather than a small number. The -1 is not exact -- it is still a + # central difference of the solve -- and it lands within ~6e-11, which is the + # difference's own round-off and not a modelling residual. + g <- grid_gradient(6.0, pars = c("vcmax_25", "stem_b", "R_d_25")) expect_identical(g$status, "no-gradient") expect_identical(g$method, "fd") - expect_equal(g$gradient["vcmax_25", "A"], -0.015, tolerance = 1e-4) + # A = -R_d, and at 25 C R_d IS the reference value. + expect_equal(g$value[["A"]], + -leaf_model()$rd_to_vcmax_ratio_ * leaf_traits()$vcmax_25) + expect_equal(g$gradient["R_d_25", "A"], -1, tolerance = 1e-8) + expect_identical(g$gradient["vcmax_25", "A"], 0) expect_equal(g$gradient["stem_b", "A"], 0) # Forcing the composite here is an error rather than a wrong number: unlike a @@ -590,11 +618,16 @@ test_that("leaf_gradient() refuses the combinations that would disagree", { test_that("the setter's positional trait call cannot drift in arity", { # `.gradient_setter()` applies traits POSITIONALLY, straight onto the object, to - # skip rebuilding a leaf_traits per perturbation. That is a hard-coded thirteen. If + # skip rebuilding a leaf_traits per perturbation. That is a hard-coded FOURTEEN. If # a trait is added to leaf_traits() and to the C++ setter, nothing about that call # fails to compile -- it would silently pass the wrong value for every argument # after the new one. So the arity is asserted here rather than trusted. - expect_length(leaf_traits(), 13L) - expect_length(formals(leaf_model()$set_traits), 13L) + # + # ⚠️ THIS TEST'S OWN PREDICTION CAME TRUE, and it is the reason the count is + # fourteen now. Adding `R_d_25` (#41) broke `.gradient_setter()` at run time and + # nowhere else, with "argument R_d_25 is missing" raised inside the generated + # binding -- a message naming neither the call nor the arity. + expect_length(leaf_traits(), 14L) + expect_length(formals(leaf_model()$set_traits), 14L) expect_identical(names(leaf_traits()), names(formals(leaf_model()$set_traits))) }) diff --git a/tests/testthat/test-surface.R b/tests/testthat/test-surface.R index 8f49bd3..9499d22 100644 --- a/tests/testthat/test-surface.R +++ b/tests/testthat/test-surface.R @@ -17,8 +17,16 @@ test_that("leaf_traits() and leaf_control() partition the C++ constructor", { covered <- c(names(leaf_traits()), names(leaf_control())) expect_setequal(setdiff(ctor_args, covered), character(0)) + # ⚠️ `R_d_25` IS A TRAIT THE CONSTRUCTOR DOES NOT TAKE, and it is listed here so + # that stays a recorded fact rather than a surprise. `leaf_model()` assigns the + # field after construction; if it ever stopped doing so, `leaf_traits(R_d_25 =)` + # would be accepted and silently ignored, which is worse than not offering the + # argument -- and this test is not what would catch that (test-leaf-model.R's + # round trip is). Extending the generated constructor is the tidier fix and was + # not taken: its argument list is positional, seventeen long, and pinned by the + # raw-versus-friendly comparison below. expect_setequal(setdiff(covered, ctor_args), - c("integration_rule", "integration_tol")) + c("R_d_25", "integration_rule", "integration_tol")) expect_length(intersect(names(leaf_traits()), names(leaf_control())), 0) # And the split is the one the issue asked for: tolerances on the control @@ -59,6 +67,36 @@ test_that("a non-default trait reaches the model through leaf_model()", { brittle <- leaf_model(leaf_traits(stem_b = 2.0)) expect_lt(brittle$proportion_of_conductivity(2.0), leaf_model()$proportion_of_conductivity(2.0)) + + # ⚠️ `R_d_25` NEEDS ITS OWN CASE, because it is the one trait the generated + # constructor does not take: `leaf_model()` assigns the field afterwards, and if + # that line went away every test above would still pass while + # `leaf_traits(R_d_25 =)` was accepted and silently ignored. See the partition + # test above for why the constructor was not extended instead. + # + # Both directions, and the sentinel too. The default derives R_d_25 as + # `rd_to_vcmax_ratio_ * vcmax_25`, so passing that product explicitly must be + # BIT-IDENTICAL to leaving it NA -- which is the check that the sentinel and the + # explicit route reach the same number rather than merely similar ones. + ratio <- leaf_model()$rd_to_vcmax_ratio_ + default_rd <- ratio * leaf_traits()$vcmax_25 + expect_identical( + leaf_solve(psi_soil = 2.0, PPFD = 900, + traits = leaf_traits(R_d_25 = default_rd))$A, + base$A) + expect_lt(leaf_solve(psi_soil = 2.0, PPFD = 900, + traits = leaf_traits(R_d_25 = 2 * default_rd))$A, + base$A) + expect_gt(leaf_solve(psi_soil = 2.0, PPFD = 900, + traits = leaf_traits(R_d_25 = 0))$A, + base$A) + + # And the sentinel is a value, not a hole: NA is accepted, a negative number is + # not, and neither is a vector -- `.check_scalars()` cannot cover this one + # because it demands finiteness. + expect_no_error(leaf_traits(R_d_25 = NA_real_)) + expect_error(leaf_traits(R_d_25 = -1), "non-negative") + expect_error(leaf_traits(R_d_25 = c(1, 2)), "a single number") }) test_that("a control setting reaches the model and is not treated as a trait", { diff --git a/tools/gradient_golden.R b/tools/gradient_golden.R index 8a61502..47ab662 100644 --- a/tools/gradient_golden.R +++ b/tools/gradient_golden.R @@ -59,24 +59,31 @@ grid_drivers <- function(psi_soil, ppfd = 900, vpd = 2.0, layers = 1L) { # function at all, so the composite must return EXACTLY zero for it at an # interior optimum and the fallback must return ~1.26 at a dry-pinned one. A pin # that omitted it would miss the sharpest statement of why there are two routes. +# +# `R_d_25` is in `pars` throughout for the opposite reason: it is the newest +# parameter (#41) and the one with no history in this file, so every row records +# it. It also makes each row's `vcmax_25` entry checkable rather than merely +# recorded -- `dY/dvcmax_25 + rd_to_vcmax_ratio_ * dY/dR_d_25` is the total +# derivative the `vcmax_25` column used to hold on its own. cases <- list( list(label = "interior-1layer", args = grid_drivers(2.0), - pars = c("vcmax_25", "stem_b", "psi_crit")), + pars = c("vcmax_25", "stem_b", "psi_crit", "R_d_25")), list(label = "interior-5layer", args = grid_drivers(0.5, vpd = 0.5, layers = 5L), - pars = c("vcmax_25", "stem_b", "psi_crit")), + pars = c("vcmax_25", "stem_b", "psi_crit", "R_d_25")), list(label = "pinned-dry-3layer", args = grid_drivers(4.0, vpd = 0.5, layers = 3L), - pars = c("vcmax_25", "stem_b", "psi_crit")), + pars = c("vcmax_25", "stem_b", "psi_crit", "R_d_25")), list(label = "shutdown-1layer", args = grid_drivers(6.0), - pars = c("vcmax_25", "stem_b", "psi_crit")), + pars = c("vcmax_25", "stem_b", "psi_crit", "R_d_25")), list(label = "single-potential", args = list(psi_soil = 1.5, PPFD = 900, atm_vpd = 2.0, supply = leaf_supply_single(), root_network = series_resistance(1e4)), - pars = c("vcmax_25", "leaf_specific_conductance_max", "resistance")) + pars = c("vcmax_25", "leaf_specific_conductance_max", "resistance", + "R_d_25")) ) out <- do.call(rbind, lapply(cases, function(cs) { diff --git a/vignettes/cpp-interface.Rmd b/vignettes/cpp-interface.Rmd index b2d55b4..7b08d3b 100644 --- a/vignettes/cpp-interface.Rmd +++ b/vignettes/cpp-interface.Rmd @@ -130,10 +130,18 @@ const std::vector out = // out[i].status is Interior / Pinned / NoGradient / Error ``` -`theta` is `g::n_pars` = 15 doubles: the thirteen traits in `set_traits`' argument -order, then `leaf_specific_conductance_max`, then the single-potential path's -`resistance`. `g::par_names()` is that order, and `pars` holds positions into it — -⚠️ appending to the enumeration is safe and reordering it is not. +`theta` is `g::n_pars` = 16 doubles: the first thirteen traits in `set_traits`' +argument order, then `leaf_specific_conductance_max`, then the single-potential +path's `resistance`, then `R_d_25`. `g::par_names()` is that order, and `pars` holds +positions into it — ⚠️ appending to the enumeration is safe and reordering it is +not, which is why `R_d_25` sits at the end (`g::par_R_d_25` = 15) rather than at 13 +where `set_traits` takes it: slotting it in would have displaced `g::par_kmax` and +`g::par_resistance`. + +⚠️ **Do not put `set_traits`' NaN sentinel in `theta`.** `R_d_25` may be NaN as a +trait, meaning *derive it from `rd_to_vcmax_ratio_ * vcmax_25`*, but a NaN in +`theta` is not differentiable — perturbing it yields NaN — so resolve it first, as +`R/gradient.R` does. `Leaf::rd_reference()` is that expression. Three things the free function gives you that a hand-rolled loop would not: @@ -157,7 +165,7 @@ The ingredients are still public, if you want to compose something else: | piece | what it is | |---|---| -| `set_traits(...)` | replace all thirteen traits, refreshing splines and the temperature cache | +| `set_traits(...)` | replace all fourteen traits, refreshing splines and the temperature cache | | `perturb_stem_b(b)` | move `stem_b` by rescaling the curve instead of rebuilding it | | `dprofit_droot_collar_psi(psi, &feasible)` | dprofit/dψ at a given collar potential | | `evaluate_root_collar_psi(psi)` | solve the inner problem at a fixed collar | diff --git a/vignettes/phylloptim.Rmd b/vignettes/phylloptim.Rmd index 4c4ba27..fb10151 100644 --- a/vignettes/phylloptim.Rmd +++ b/vignettes/phylloptim.Rmd @@ -338,9 +338,18 @@ dim(leaf_gradient(psi_soil = 2.0, PPFD = 900)$gradient) rownames(leaf_gradient(psi_soil = 2.0, PPFD = 900)$gradient) ``` -Fourteen on the multi-layer path — the thirteen traits from `leaf_traits()`, plus +Fifteen on the multi-layer path — the fourteen traits from `leaf_traits()`, plus `leaf_specific_conductance_max`, which is not a trait but is fitted like one. The -single-potential path adds `resistance`, making fifteen. +single-potential path adds `resistance`, making sixteen. + +⚠️ `R_d_25` comes last rather than in `leaf_traits()`' own order, which puts it +fourteenth. The enumeration appends it because inserting it would have moved +`leaf_specific_conductance_max` and `resistance`, and the C++ side indexes this +list by position. Its value defaults to `NA`, meaning *derive it as +`rd_to_vcmax_ratio_ * vcmax_25`* — and it is differentiable **at that default**, +which is what makes `dY/dvcmax_25` a partial at fixed respiration rather than the +total derivative it used to be. If you want the total, add +`rd_to_vcmax_ratio_ * dY/dR_d_25` back. **Selecting fewer genuinely costs less**: the work is one solve plus two cheap evaluations per parameter, so it scales with what you ask for. @@ -353,7 +362,12 @@ bench <- function(pars) { as.numeric(Sys.time() - t0, units = "secs") / 20 * 1000 } tibble::tibble( - request = c("`pars = NULL` (all 16)", "4 parameters", "1 parameter"), + # Counted, not written down: this label said 16 for a while when the answer was + # 14, which is exactly the way a number beside a chunk rots (the chunk runs, the + # prose next to it is never asserted). + request = c(sprintf("`pars = NULL` (all %d)", + nrow(leaf_gradient(psi_soil = 2.0, PPFD = 900)$gradient)), + "4 parameters", "1 parameter"), `ms per call` = round(c(bench(NULL), bench(c("vcmax_25", "jmax_25", "stem_b", "cost_scale_TF24")), From f919e24442fd5217c4be6c4135c431eedd605d44 Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Mon, 10 Aug 2026 19:21:16 +1000 Subject: [PATCH 06/13] An escape hatch back to the pre-#41 R_d shape (#41) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rd_tracks_vcmax_ restores R_d = rd_to_vcmax_ratio_ * vcmax_(T), Vcmax's peaked Arrhenius, bit-identically to the pre-#41 model. ⚠️ This closes a reproducibility hole we made rather than adding an option. No combination of rd_q10_intercept_ and rd_q10_slope_ produces a PEAKED function, so without it no published plant result computed under the old shape could be regenerated. It also makes the plant revalidation a controlled A/B instead of an argument. In the temperature cache key, because flipping it changes R_d at every temperature but 25 C and nothing else the key mentions -- a key that missed it would take a cache hit and run the whole comparison under whichever shape was seated first. Setting it with a measured R_d_25 is refused rather than resolved. The blast-radius table's "old" column is now the flag rather than an emulation of it; its printed numbers are unchanged. plant binds Leaf's fields by name, so it needs its own line for this one. 3.03-3.04 us/solve on both arms, interleaved x3 from one tree, identical checksums. Golden bit-identical; 496 C++ checks, 940 R. Co-Authored-By: Claude Opus 5 (1M context) --- NEWS.md | 43 +++++++++++++ R/RcppExports.R | 8 +++ R/RcppR6.R | 9 ++- inst/RcppR6_classes.yml | 8 +++ inst/include/phylloptim/leaf_model.hpp | 59 ++++++++++++++++-- src/RcppExports.cpp | 24 ++++++++ src/RcppR6.cpp | 9 +++ tests/cpp/test_leaf.cpp | 70 ++++++++++++++++++++-- tests/testthat/test-temperature-response.R | 36 +++++++++++ 9 files changed, 255 insertions(+), 11 deletions(-) diff --git a/NEWS.md b/NEWS.md index 80485f8..75470f0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,48 @@ # phylloptim 0.2.1 +## An escape hatch back to the pre-#41 respiration shape (#41) + +`rd_tracks_vcmax_` makes `R_d` be `rd_to_vcmax_ratio_ * vcmax_(T)` again — Vcmax's +peaked Arrhenius — bit-identically to what this model computed before #41. + +⚠️ **This closes a reproducibility hole we made.** No combination of +`rd_q10_intercept_` and `rd_q10_slope_` produces a *peaked* function, so with #41 +landed and no flag, **any published plant result computed under the old shape could +not be regenerated with this code.** It is not a deprecation switch or a +compatibility mode: the default shape is the correct one, and this reproduces a shape +known to be wrong above the thermal optimum. It exists so an old number can be +checked, and so the plant revalidation is a controlled A/B — the flag on with +temperature varying isolates the shape change from everything else on the branch — +rather than an argument. + +The two shapes agree exactly at 25 °C and diverge in **opposite directions** above +the thermal optimum: at 45 °C the peaked curve gives `R_d` 0.507, below its 25 °C +value of 1.440, where the declining-Q10 form gives 3.618. That opposition is why a +flag was needed and a parameter would not do. + +Three things it had to get right: + +- ⚠️ **It is in the temperature cache key.** Flipping it changes `R_d` at every + temperature but 25 °C while leaving every other key entry alone, so a key that + missed it would take a cache *hit* on the first `set_physiology()` after the flip + and run the whole A/B under whichever shape was seated first (hazard 10). +- ⚠️ **Setting it together with a measured `R_d_25` is REFUSED, not resolved.** The + peaked curve has no reading in which a measured reference value means anything, so + a caller who sets both is confused about which model they are running. +- **The branch is asserted bit-exactly**, against the same `ratio * vcmax_(T)` + emulation the blast-radius table used to build for itself — and that table's "old" + column is now the flag rather than an emulation of it, so the table is evidence the + hatch reproduces what plant used to compute rather than only a record of what + changed. Its printed numbers are unchanged. + +`plant` binds `Leaf`'s fields by name in its own `RcppR6_classes.yml`, so it needs +its own line for this field. + +**No cost**: 3.03–3.04 µs/solve on both arms, interleaved ×3 from one tree, with +identical checksums — inside the ±0.01 within-process noise. The key is compared +once per `set_physiology()`, not per solve iteration. Golden file bit-identical. + + ## `R_d_25` is settable and differentiable from R, at its default as well as when pinned (#41) `leaf_traits(R_d_25 = 0.525)` now reaches the model, and `"R_d_25"` is a `pars` diff --git a/R/RcppExports.R b/R/RcppExports.R index bb8852f..819e202 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -485,6 +485,14 @@ Leaf__rd_q10_slope___set <- function(obj_, value) { invisible(.Call('_phylloptim_Leaf__rd_q10_slope___set', PACKAGE = 'phylloptim', obj_, value)) } +Leaf__rd_tracks_vcmax___get <- function(obj_) { + .Call('_phylloptim_Leaf__rd_tracks_vcmax___get', PACKAGE = 'phylloptim', obj_) +} + +Leaf__rd_tracks_vcmax___set <- function(obj_, value) { + invisible(.Call('_phylloptim_Leaf__rd_tracks_vcmax___set', PACKAGE = 'phylloptim', obj_, value)) +} + Leaf__PPFD___get <- function(obj_) { .Call('_phylloptim_Leaf__PPFD___get', PACKAGE = 'phylloptim', obj_) } diff --git a/R/RcppR6.R b/R/RcppR6.R index 7c29932..8fa2ad1 100644 --- a/R/RcppR6.R +++ b/R/RcppR6.R @@ -1,6 +1,6 @@ ## Generated by RcppR6: do not edit by hand ## Version: 0.2.4 -## Hash: 70f61323fadca98ceb4240cd8fcb32ad +## Hash: 60b3e38c507c8fe5f85c1d7372f9dd00 ##' @importFrom Rcpp evalCpp ##' @importFrom R6 R6Class @@ -488,6 +488,13 @@ NULL Leaf__rd_q10_slope___set(self, value) } }, + rd_tracks_vcmax_ = function(value) { + if (missing(value)) { + Leaf__rd_tracks_vcmax___get(self) + } else { + Leaf__rd_tracks_vcmax___set(self, value) + } + }, PPFD_ = function(value) { if (missing(value)) { Leaf__PPFD___get(self) diff --git a/inst/RcppR6_classes.yml b/inst/RcppR6_classes.yml index 611d13a..12e6109 100644 --- a/inst/RcppR6_classes.yml +++ b/inst/RcppR6_classes.yml @@ -224,6 +224,14 @@ Leaf: # by 45 C. See NEWS for the blast radius. rd_q10_intercept_: {type: double, access: field} rd_q10_slope_: {type: double, access: field} + # ⚠️ THE PRE-#41 RESPIRATION SHAPE, and the only way back to it: R_d becomes + # rd_to_vcmax_ratio_ * vcmax_(T), bit-identical to what this model did before + # #41, and the two Q10 coefficients above are not consulted. It exists because + # no combination of them produces a PEAKED function, so without it no published + # plant result computed under the old shape could be regenerated. Bound so the + # plant A/B can be driven from R. Setting it together with a measured R_d_25 is + # refused rather than resolved. + rd_tracks_vcmax_: {type: bool, access: field} # --- drivers, as last set by set_physiology ------------------------------ PPFD_: {type: double, access: field} diff --git a/inst/include/phylloptim/leaf_model.hpp b/inst/include/phylloptim/leaf_model.hpp index 673a47c..6f8ed16 100644 --- a/inst/include/phylloptim/leaf_model.hpp +++ b/inst/include/phylloptim/leaf_model.hpp @@ -381,6 +381,29 @@ class Leaf { // rather than the only option. double rd_q10_intercept_ = 3.09; double rd_q10_slope_ = 0.0430; + // ⚠️ THE PRE-#41 RESPIRATION SHAPE, AND THE ONLY WAY BACK TO IT. With this set, + // `R_d_ = rd_to_vcmax_ratio_ * vcmax_` -- Vcmax's peaked Arrhenius, bit-identical + // to what this model did before #41 -- and the Q10 coefficients above are not + // consulted at all. + // + // It exists because the alternative was worse than a flag. No combination of + // `rd_q10_intercept_` and `rd_q10_slope_` produces a PEAKED function, so without + // this the old shape was unreachable and **no published plant result computed + // under it could be regenerated with this code**. That is a reproducibility hole + // we made, not a feature request. + // + // It is also what turns the plant revalidation from an argument into a controlled + // A/B: with the flag on, T varying, the answer must be bit-identical to + // pre-#41 plant, which isolates the shape change from everything else in the + // same branch. ⚠️ plant binds Leaf's fields by name in its own + // RcppR6_classes.yml, so it needs its own line for this one. + // + // ⚠️ NOT a deprecation switch and not a "compatibility mode": the default shape + // is the correct one, and this reproduces a shape known to be wrong above the + // thermal optimum. Setting it together with a measured `R_d_25` is REFUSED rather + // than resolved -- see update_temperature_dependent_params -- because the old + // shape has no reading in which a measured reference value means anything. + bool rd_tracks_vcmax_ = false; double atm_kpa_; // Conversion from a mixing ratio (umol mol^-1) to a partial pressure (Pa). // DERIVED from atm_kpa_, not a constant: it is 1e-6 * P, so the old @@ -456,7 +479,7 @@ class Leaf { // * the cost is 17 double comparisons per set_physiology() call, i.e. per // driver set, NOT per inner solve iteration. Measured: within run-to-run // noise on bench_solve. - static constexpr int photo_temp_key_size = 19; + static constexpr int photo_temp_key_size = 20; std::array photo_temp_cache_key_{}; std::array photo_temp_key() const; // Dark respiration at 25 C, with the sentinel resolved. ⚠️ Used by BOTH the @@ -2488,7 +2511,14 @@ inline std::array Leaf::photo_temp_key() cons // keeps NaN out of an `==` comparison, and it is also more complete: // it invalidates on a change to whichever of the two is actually in // force, and on neither when the other is. - rd_reference(), rd_q10_intercept_, rd_q10_slope_}; + rd_reference(), rd_q10_intercept_, rd_q10_slope_, + // A bool in an array of doubles, because the key is one contiguous + // `==` comparison and 0.0/1.0 compares exactly. It has to be here: + // flipping the flag changes R_d at every temperature but 25 C while + // leaving every other key entry alone, so without it the first + // set_physiology() after the flip takes a cache HIT and the whole + // A/B runs under whichever shape happened to be seated first. + rd_tracks_vcmax_ ? 1.0 : 0.0}; } inline double Leaf::rd_reference() const { @@ -2522,9 +2552,28 @@ inline void Leaf::update_temperature_dependent_params(double leaf_temp) { // // The reference value is a sentinel-defaulted parameter so that a caller who // sets `vcmax_25` still gets respiration that scales with it (see R_d_25). - const double q10 = - rd_q10_intercept_ - rd_q10_slope_ * (leaf_temp + 25.0) / 2.0; - R_d_ = rd_reference() * std::pow(q10, (leaf_temp - 25.0) / 10.0); + if (rd_tracks_vcmax_) { + // The pre-#41 shape, for reproducing a result computed under it. Written as + // the same expression the old code used rather than as `rd_reference() * + // vcmax_ / vcmax_25`, which is algebraically equal and not bit-equal -- + // bit-equality with the old model is the entire purpose of this branch. + // + // ⚠️ Refused rather than resolved. `R_d_25` is a measured reference value and + // the peaked curve has no reading in which one means anything, so a caller who + // sets both is confused about which model they are running. The Q10 + // coefficients above are simply unused here, which is different: they are + // defaults the caller did not ask for. + if (!std::isnan(R_d_25)) { + util::stop("rd_tracks_vcmax_ reproduces the pre-#41 shape, in which R_d is " + "rd_to_vcmax_ratio_ * vcmax_(T) and a measured R_d_25 has no " + "meaning. Set one or the other, not both."); + } + R_d_ = rd_to_vcmax_ratio_ * vcmax_; + } else { + const double q10 = + rd_q10_intercept_ - rd_q10_slope_ * (leaf_temp + 25.0) / 2.0; + R_d_ = rd_reference() * std::pow(q10, (leaf_temp - 25.0) / 10.0); + } km_ = (kc_*umol_per_mol_to_Pa_)*(1 + (atm_o2_kpa_*kPa_to_Pa)/(ko_*umol_per_mol_to_Pa_)); electron_transport_ = electron_transport(); } diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index ba5d395..21e2e90 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -1417,6 +1417,28 @@ BEGIN_RCPP return R_NilValue; END_RCPP } +// Leaf__rd_tracks_vcmax___get +bool Leaf__rd_tracks_vcmax___get(phylloptim::RcppR6::RcppR6 obj_); +RcppExport SEXP _phylloptim_Leaf__rd_tracks_vcmax___get(SEXP obj_SEXP) { +BEGIN_RCPP + Rcpp::RObject rcpp_result_gen; + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); + rcpp_result_gen = Rcpp::wrap(Leaf__rd_tracks_vcmax___get(obj_)); + return rcpp_result_gen; +END_RCPP +} +// Leaf__rd_tracks_vcmax___set +void Leaf__rd_tracks_vcmax___set(phylloptim::RcppR6::RcppR6 obj_, bool value); +RcppExport SEXP _phylloptim_Leaf__rd_tracks_vcmax___set(SEXP obj_SEXP, SEXP valueSEXP) { +BEGIN_RCPP + Rcpp::RNGScope rcpp_rngScope_gen; + Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); + Rcpp::traits::input_parameter< bool >::type value(valueSEXP); + Leaf__rd_tracks_vcmax___set(obj_, value); + return R_NilValue; +END_RCPP +} // Leaf__PPFD___get double Leaf__PPFD___get(phylloptim::RcppR6::RcppR6 obj_); RcppExport SEXP _phylloptim_Leaf__PPFD___get(SEXP obj_SEXP) { @@ -2381,6 +2403,8 @@ static const R_CallMethodDef CallEntries[] = { {"_phylloptim_Leaf__rd_q10_intercept___set", (DL_FUNC) &_phylloptim_Leaf__rd_q10_intercept___set, 2}, {"_phylloptim_Leaf__rd_q10_slope___get", (DL_FUNC) &_phylloptim_Leaf__rd_q10_slope___get, 1}, {"_phylloptim_Leaf__rd_q10_slope___set", (DL_FUNC) &_phylloptim_Leaf__rd_q10_slope___set, 2}, + {"_phylloptim_Leaf__rd_tracks_vcmax___get", (DL_FUNC) &_phylloptim_Leaf__rd_tracks_vcmax___get, 1}, + {"_phylloptim_Leaf__rd_tracks_vcmax___set", (DL_FUNC) &_phylloptim_Leaf__rd_tracks_vcmax___set, 2}, {"_phylloptim_Leaf__PPFD___get", (DL_FUNC) &_phylloptim_Leaf__PPFD___get, 1}, {"_phylloptim_Leaf__PPFD___set", (DL_FUNC) &_phylloptim_Leaf__PPFD___set, 2}, {"_phylloptim_Leaf__atm_vpd___get", (DL_FUNC) &_phylloptim_Leaf__atm_vpd___get, 1}, diff --git a/src/RcppR6.cpp b/src/RcppR6.cpp index 1315f2d..4381f47 100644 --- a/src/RcppR6.cpp +++ b/src/RcppR6.cpp @@ -527,6 +527,15 @@ void Leaf__rd_q10_slope___set(phylloptim::RcppR6::RcppR6 obj_, obj_->rd_q10_slope_ = value; } +// [[Rcpp::export]] +bool Leaf__rd_tracks_vcmax___get(phylloptim::RcppR6::RcppR6 obj_) { + return obj_->rd_tracks_vcmax_; +} +// [[Rcpp::export]] +void Leaf__rd_tracks_vcmax___set(phylloptim::RcppR6::RcppR6 obj_, bool value) { + obj_->rd_tracks_vcmax_ = value; +} + // [[Rcpp::export]] double Leaf__PPFD___get(phylloptim::RcppR6::RcppR6 obj_) { return obj_->PPFD_; diff --git a/tests/cpp/test_leaf.cpp b/tests/cpp/test_leaf.cpp index 24a7641..ddfae8c 100644 --- a/tests/cpp/test_leaf.cpp +++ b/tests/cpp/test_leaf.cpp @@ -2202,7 +2202,11 @@ void test_rd_temperature_response() { "R_d still scales with vcmax_25 while R_d_25 is unset"); } - // THE BLAST RADIUS. Old form emulated as ratio * vcmax_(T) via q10 = 1. + // THE BLAST RADIUS. The old form is the `rd_tracks_vcmax_` branch itself, so the + // "old" column below is the escape hatch rather than an emulation of it -- which + // makes this table evidence that the hatch reproduces what plant used to compute, + // not merely a record of what changed. The emulation it used to use survives just + // above, as the bit-exactness check on the branch. // // ⚠️⚠️ AND A LIMIT THIS CHANGE MAKES REACHABLE, which is the most important thing // here. A higher R_d can drive net assimilation negative across the WHOLE @@ -2218,6 +2222,65 @@ void test_rd_temperature_response() { // Recorded as a measured limit rather than avoided by choosing a cooler sweep: // the temperature at which the model stops having an operating point is exactly // what a caller needs to know, and it moved. + // ⚠️ THE ESCAPE HATCH BACK TO THE OLD SHAPE, and it is checked against the same + // emulation the blast-radius table below uses rather than against a recorded + // number. That is the strong form: the table's "then" arm and `rd_tracks_vcmax_` + // are two independent routes to `rd_to_vcmax_ratio_ * vcmax_(T)`, so if either + // drifts they stop agreeing. BIT-EXACT, deliberately -- reproducing an old plant + // result is the whole reason the flag exists, and "close" does not reproduce it. + { + for (double T : {15.0, 25.0, 35.0, 40.0, 45.0}) { + phylloptim::Leaf old_shape = make_leaf(d, {2.0}, {1.0}); + old_shape.rd_tracks_vcmax_ = true; + old_shape.update_temperature_dependent_params(T); + + phylloptim::Leaf emulated = make_leaf(d, {2.0}, {1.0}); + emulated.update_temperature_dependent_params(T); // seat vcmax_(T) + ok(old_shape.R_d_ == 0.015 * emulated.vcmax_, + "rd_tracks_vcmax_ reproduces ratio * vcmax_(T) bit-exactly"); + // And it really is PEAKED, which is the property no Q10 can imitate: R_d + // above the thermal optimum is BELOW its 25 C value under the old shape and + // above it under the new one. + if (T == 45.0) { + phylloptim::Leaf at25 = make_leaf(d, {2.0}, {1.0}); + at25.rd_tracks_vcmax_ = true; + at25.update_temperature_dependent_params(25.0); + ok(old_shape.R_d_ < at25.R_d_, + "and it falls above the thermal optimum, as the old shape did"); + phylloptim::Leaf now45 = make_leaf(d, {2.0}, {1.0}); + now45.update_temperature_dependent_params(45.0); + ok(now45.R_d_ > at25.R_d_, "where the declining-Q10 form rises"); + } + } + + // ⚠️ The flag must be IN THE CACHE KEY. Flipping it on a leaf that has already + // been driven changes R_d at every temperature but 25 C and nothing else the + // key mentions, so a key that missed it would take a HIT here and silently run + // the whole comparison under whichever shape was seated first (hazard 10). + phylloptim::Leaf flipped = make_leaf(d, {2.0}, {1.0}); + flipped.update_temperature_dependent_params(40.0); + const double rd_new_shape = flipped.R_d_; + flipped.rd_tracks_vcmax_ = true; + flipped.set_physiology(fixture::root_network({1.0 / d.area_leaf}, {1.0}), + d.PPFD, {2.0}, {1.0}, d.K_s * d.theta / d.h, + d.atm_vpd, d.ca, 40.0, d.atm_o2_kpa, d.atm_kpa); + ok(flipped.R_d_ != rd_new_shape, + "setting rd_tracks_vcmax_ invalidates the temperature cache"); + + // Refused rather than resolved: the old shape has no reading in which a + // measured reference value means anything. + phylloptim::Leaf both = make_leaf(d, {2.0}, {1.0}); + both.rd_tracks_vcmax_ = true; + both.R_d_25 = 0.525; + bool threw = false; + try { + both.update_temperature_dependent_params(30.0); + } catch (const std::runtime_error &) { + threw = true; + } + ok(threw, "rd_tracks_vcmax_ with a measured R_d_25 is refused, not resolved"); + } + // ⚠️ THE LABEL BELOW SAID "Q10 = 2" AND THAT WAS STALE. A constant Q10 of 2 was // the first implementation and was rejected on measurement (R_d 4.07 and -73% on // A at 40 C, no operating point at all by 45 C); the "now" arm here is the @@ -2241,10 +2304,7 @@ void test_rd_temperature_response() { bool then_ok = true; try { phylloptim::Leaf then = make_leaf(d, {2.0}, {1.0}); - then.update_temperature_dependent_params(T); // seat vcmax_(T) - then.R_d_25 = 0.015 * then.vcmax_; // the old R_d at this T - then.rd_q10_intercept_ = 1.0; // and no Q10 scaling at all - then.rd_q10_slope_ = 0.0; + then.rd_tracks_vcmax_ = true; then.update_temperature_dependent_params(T); then.find_root_collar_psi(); A_then = then.assim_colimited_; diff --git a/tests/testthat/test-temperature-response.R b/tests/testthat/test-temperature-response.R index 6ffbc94..bcee722 100644 --- a/tests/testthat/test-temperature-response.R +++ b/tests/testthat/test-temperature-response.R @@ -96,3 +96,39 @@ test_that("rd_to_vcmax_ratio_ reaches the solve", { # range a calibration actually needs, not an extreme. expect_lt(drive(0.0302), drive(0.0046)) }) + +test_that("rd_tracks_vcmax_ restores the pre-#41 respiration shape from R", { + # ⚠️ THIS IS A REPRODUCIBILITY ESCAPE HATCH, NOT A MODELLING OPTION. `R_d` used to + # be `rd_to_vcmax_ratio_ * vcmax_(T)`, tracking Vcmax's PEAKED Arrhenius, and no + # combination of `rd_q10_intercept_` and `rd_q10_slope_` produces a peaked + # function -- so without this flag no published plant result computed under the + # old shape could be regenerated. The C++ suite pins the branch bit-exactly; what + # this test adds is that it is reachable from R at all, which is what the plant + # A/B needs. + rd_at <- function(temp, old_shape) { + l <- leaf_model() + l$rd_tracks_vcmax_ <- old_shape + set_drivers(l, psi_soil = 0.5, PPFD = 900, leaf_temp = temp) + c(R_d = l$R_d_, vcmax = l$vcmax_) + } + + ratio <- leaf_model()$rd_to_vcmax_ratio_ + for (temp in c(15, 25, 35, 45)) { + old <- rd_at(temp, TRUE) + expect_identical(old[["R_d"]], ratio * old[["vcmax"]], + label = sprintf("old shape at %g C", temp)) + } + + # The two shapes agree at the 25 C reference and diverge in OPPOSITE DIRECTIONS + # above the thermal optimum -- the peaked curve falls, the declining-Q10 curve + # rises. That opposition is the reason a flag was needed rather than a parameter. + expect_identical(rd_at(25, TRUE)[["R_d"]], rd_at(25, FALSE)[["R_d"]]) + expect_lt(rd_at(45, TRUE)[["R_d"]], rd_at(25, TRUE)[["R_d"]]) + expect_gt(rd_at(45, FALSE)[["R_d"]], rd_at(25, FALSE)[["R_d"]]) + + # And it is refused rather than resolved alongside a measured reference value. + l <- leaf_model(leaf_traits(R_d_25 = 0.525)) + l$rd_tracks_vcmax_ <- TRUE + expect_error(set_drivers(l, psi_soil = 0.5, PPFD = 900, leaf_temp = 30), + "not both") +}) From d6530bd87449e469e3e583e56e827b4713542660 Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Mon, 10 Aug 2026 21:00:25 +1000 Subject: [PATCH 07/13] Give the CI consumer all n_pars, not fifteen (#41) The inline consumer/main.cpp in cpp-tests.yml initialises theta with a brace list, which compiles and zero-fills whatever it omits. Appending R_d_25 to the enumeration therefore made it pass 0.0 -- a leaf with no respiration -- with no diagnostic, and its arbitrated dA/dvcmax_25 check still carried the pre-#41 total derivative. Both fixed and verified by extracting the two heredocs and building the consumer locally, which is the only way to see this: dA/dvcmax_25 = 0.020934892290554417, matching the recorded gradient, profit unchanged, exit 0. ctest 2/2. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/cpp-tests.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cpp-tests.yml b/.github/workflows/cpp-tests.yml index 01b54f3..931bd9c 100644 --- a/.github/workflows/cpp-tests.yml +++ b/.github/workflows/cpp-tests.yml @@ -188,10 +188,16 @@ jobs: d.PPFD = 900; d.psi_soil = {2.0}; d.soil_depth = soil_depth; d.atm_vpd = 2.0; d.ca = 40.0; d.leaf_temp = 25.0; d.atm_o2_kpa = 21.0; d.atm_kpa = 101.3; + // ⚠️ ALL n_pars ELEMENTS, WRITTEN OUT. A short initialiser compiles + // and zero-fills the rest, so when #41 appended R_d_25 this list + // silently supplied 0.0 for it -- a leaf with no respiration -- and + // the only symptom was the arbitrated gradient below. The last entry + // is the RESOLVED reference value: theta must never carry + // set_traits' NaN sentinel, because a NaN is not differentiable. double theta[phylloptim::gradient::n_pars] = { 96.0, 2.680147, 3.898245, 5.870283, 2.680147, 3.898245, 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, - 1.0 * 0.000157 / 5.0, 0.0}; + 1.0 * 0.000157 / 5.0, 0.0, 0.015 * 96.0}; const int pars[1] = {0}; // vcmax_25 const std::vector obs{d, d}; const std::vector g = @@ -207,7 +213,12 @@ jobs: } // The R layer's arbitrated reference for this operating point, loosely // compared for the same reason profit is below. - if (std::fabs(g[0].grad[0] - 0.0172086) > 1e-5) { + // + // ⚠️ This read 0.0172086 until #41. That was the TOTAL derivative, with + // respiration following vcmax_25; with R_d_25 a parameter of its own + // this is the PARTIAL at fixed respiration, and the difference is + // rd_to_vcmax_ratio_ * dA/dR_d_25. It is not a change in the model. + if (std::fabs(g[0].grad[0] - 0.0209349) > 1e-5) { return 1; } l.set_physiology(roots, 900, {2.0}, soil_depth, From 520a33f2d06ffeddcd1ce064e5313534c611b0f3 Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Mon, 10 Aug 2026 21:00:47 +1000 Subject: [PATCH 08/13] A temperature axis for the golden grid: 288 -> 1152 (#41) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠️ The golden file was blind to every temperature response in the model. Its 288 points were all at 25 C, where the reference values of Vcmax, Jmax and R_d are DEFINED -- so a change to any response curve is inert there by construction. #41 changed R_d's shape at every temperature except 25 C and this file did not move a bit. Now the same state grid at 15 / 25 / 35 / 40 C, with a leaf_temp column. 40 C is included deliberately: it is where the response bites hardest, and the shut-down rows at the hot end pin the limit. Deliberate regeneration, and checkable as an ADDITION: temperature is the OUTERMOST loop, so the 25 C block is BYTE-IDENTICAL to the pre-#41 file in all nine output columns. 864 rows added, none moved. The classification is counted per temperature now, because it moves -- dry-pinned 18/18/3/0 against wet-pinned 24/24/43/80. A hot leaf has less to gain from water, so its optimum presses against the WET bound. The 48 shut-down rows are temperature-independent, as hydraulics rather than heat is what forbids transpiration there. bench_solve deliberately stays at 288 points at 25 C: a timing baseline is only useful against its own history. Co-Authored-By: Claude Opus 5 (1M context) --- .claude/CLAUDE.md | 16 +- NEWS.md | 52 + inst/include/phylloptim/leaf_model.hpp | 6 +- tests/cpp/bench_solve.cpp | 13 +- tests/cpp/golden/operating_points.tsv | 1442 +++++++++++++++++++----- tests/cpp/test_golden.cpp | 174 ++- tests/cpp/test_leaf.cpp | 2 +- tests/validate/compare_with_plant.R | 31 +- 8 files changed, 1376 insertions(+), 360 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 0e29fca..bc8c5c9 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -72,7 +72,8 @@ tests/cpp/ plain-C++ suite, no R, no framework tests/cpp/root_network.hpp the suite's root-architecture fixture: the two ex-Leaf-default beta_R_* constants, in ONE place because the golden file's bit-exactness depends on them -tests/cpp/golden/ bit-exact regression baseline, 288 operating points +tests/cpp/golden/ bit-exact regression baseline, 1152 operating points + -- the 288-point state grid at 4 leaf temperatures tests/cpp/bench_solve.cpp timing harness for the collar solve (hazard 5) tests/cpp/bench_gradient.cpp timing harness for a TRAIT GRADIENT: the IFT composite against differencing the solve, with @@ -276,13 +277,24 @@ while looking like history. Two rows were produced that way before it was notice ## The golden file is the safety net — treat it that way -`tests/cpp/golden/operating_points.tsv` records 288 operating points and is +`tests/cpp/golden/operating_points.tsv` records 1152 operating points and is compared **bit-exactly** (`%.17g` round-trips a double). It is what makes a large refactor of this code checkable rather than hopeful, and it earned that role repeatedly: it proved three "surely dead" `set_physiology` arguments really were dead, confined the shutdown fix to exactly 48 rows × 5 fields, and showed the `area_leaf` change was 2 ULP. +⚠️ **It was 288 points until #41, all at one leaf temperature, and that made it +blind to every temperature response in the model.** The reference values of Vcmax, +Jmax and R_d are *defined* at 25 °C, so a change to any response curve is inert +there **by construction** — #41 changed R_d's shape at every temperature except +25 °C and the file did not move a bit. It is now the same 288-point state grid at +15 / 25 / 35 / 40 °C, with temperature as the OUTERMOST loop so the 25 °C block +stayed byte-identical through the regeneration. Read a bit-identical run +accordingly: it is evidence about the temperature responses now and it was not +before — and the classification it prints is per temperature, because points move +between branches as the leaf warms (dry-pinned 18 → 0, wet-pinned 24 → 80). + **Only run `make golden` deliberately.** Running it after an accidental change rubber-stamps the change. If a diff is intended, regenerate and say so in the commit message with the measured size of the change. diff --git a/NEWS.md b/NEWS.md index 75470f0..353f68d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,57 @@ # phylloptim 0.2.1 +## The golden grid has a temperature axis: 288 points become 1152 (#41) + +⚠️ **The golden file was blind to every temperature response in the model, and had +been all along.** Its grid was 6 ψ_soil × 4 PPFD × 4 VPD × 3 layer counts, **all at +a leaf temperature of 25 °C** — and the reference values of Vcmax, Jmax and R_d are +*defined* at 25 °C, so a change to any response curve is inert there **by +construction**. #41 changed R_d's shape at every temperature except 25 °C and this +file did not move a bit. The same blindness covered the thirteen temperature-response +parameters bound just before it. + +The grid is now that same state space at **15 / 25 / 35 / 40 °C** — 1152 rows, with a +`leaf_temp` column. 40 °C is in the list deliberately: it is where the response bites +hardest, and the extra shut-down rows at the hot end pin the temperature at which the +model stops having an operating point, which is a limit that moved in #41. + +**Regenerated deliberately, and the regeneration is checkable as an ADDITION rather +than taken on trust.** Temperature is the OUTERMOST loop, so the file is four +contiguous copies of the original grid, and the 25 °C block is **byte-identical** to +the pre-#41 file in all nine output columns. Nothing moved; 864 rows were added. + +**The classification is now counted per temperature, and it moves:** + +| T | interior | pinned wet | pinned dry | shutdown | +|---|---|---|---|---| +| 15 °C | 198 | 24 | 18 | 48 | +| 25 °C | 198 | 24 | 18 | 48 | +| 35 °C | 194 | 43 | 3 | 48 | +| 40 °C | 160 | 80 | 0 | 48 | + +A single total would have let points move between branches and still add up. The +direction is physical: a hot leaf assimilates less and respires more, so it has less +to gain from water and its optimum presses against the **wet** bound instead of the +dry one. The 48 shut-down rows are temperature-*independent*, which is also right — +those are the ψ_soil = 6 MPa rows, where hydraulics forbid transpiration whatever the +temperature. + +Two things the hot end does **not** reach, recorded so the zeros are not read as +coverage: `shade-death` (that is reached by light, not by heat) and the +compensation-point exit, which needs about 45 °C at the defaults. +`test_rd_temperature_response` covers the latter. + +`tests/cpp/bench_solve.cpp` deliberately did **not** follow. A timing baseline is +only useful against its own history — `tools/cost-baseline.tsv` and +`tools/bench_history.sh` compare across commits — so quadrupling its workload would +end that history to measure nothing new about the solve. Its comment no longer claims +to cover the same state space as the baseline. + +`tests/validate/compare_with_plant.R` mirrors the grid, so it gained the axis too. +⚠️ At 15 / 35 / 40 °C phylloptim and a pre-#41 plant are *expected* to differ, since +R_d's shape changed; `rd_tracks_vcmax_` is what makes that arm comparable. + + ## An escape hatch back to the pre-#41 respiration shape (#41) `rd_tracks_vcmax_` makes `R_d` be `rd_to_vcmax_ratio_ * vcmax_(T)` again — Vcmax's diff --git a/inst/include/phylloptim/leaf_model.hpp b/inst/include/phylloptim/leaf_model.hpp index 6f8ed16..6b477e4 100644 --- a/inst/include/phylloptim/leaf_model.hpp +++ b/inst/include/phylloptim/leaf_model.hpp @@ -1065,7 +1065,8 @@ class Leaf { // operating point in this state reads NA sentinels. Unsolved, // Interior profit maximum: dprofit == 0 was solved for, strictly inside the - // feasible collar interval. 198 of the 288 golden grid points. + // feasible collar interval. 198 of the 288 golden grid points at 25 C -- 160 of + // them at 40 C, where the optimum presses against the WET bound instead. Interior, // Constrained optimum pinned at the WET end of the feasible interval, just // inside root_zero_E (the collar at which uptake is exactly zero). profit is @@ -1082,7 +1083,8 @@ class Leaf { // Shutdown on water: no collar potential both moves water and stays inside // the stem's and the root's critical potentials. The stem holds at psi_crit, // transpiration is zero, and the leaf pays respiration plus the hydraulic - // cost there. 48 of the 288 golden grid points. The water response is zero; + // cost there. 48 of the 288 golden grid points at every temperature, since it is + // hydraulics rather than heat that forbids transpiration. The water response is zero; // the carbon response is not. HydraulicShutdown, // Shutdown on light: assim_max_ < 0, so gross assimilation at ci = ca cannot diff --git a/tests/cpp/bench_solve.cpp b/tests/cpp/bench_solve.cpp index 8579b26..bbb7744 100644 --- a/tests/cpp/bench_solve.cpp +++ b/tests/cpp/bench_solve.cpp @@ -8,9 +8,16 @@ // kept because the question recurs (issue #3 asks the same thing about lambda, // and gets a different answer). // -// Workload is the golden-file grid: 288 operating points over psi_soil, PPFD, -// VPD and 1/3/5 soil layers, i.e. the same state space the regression baseline -// covers, shutdown corner included. +// Workload is 288 operating points over psi_soil, PPFD, VPD and 1/3/5 soil layers, +// all at a leaf temperature of 25 C, shutdown corner included. +// +// ⚠️ That WAS the golden-file grid and is now a subset of it: #41 gave the golden +// grid a temperature axis (4 temperatures, 1152 points) and this harness +// deliberately did not follow. A timing baseline is only useful against its own +// history -- tools/cost-baseline.tsv and tools/bench_history.sh compare across +// commits -- and quadrupling the workload would end that history to measure nothing +// new about the solve. If a temperature-dependent cost ever needs measuring, add a +// second workload rather than growing this one. // // Reports min-of-N, not mean. This is a deterministic computation on a noisy // machine, so the minimum is the least-contaminated estimate of its cost; the diff --git a/tests/cpp/golden/operating_points.tsv b/tests/cpp/golden/operating_points.tsv index 2191e6a..80827b1 100644 --- a/tests/cpp/golden/operating_points.tsv +++ b/tests/cpp/golden/operating_points.tsv @@ -1,289 +1,1153 @@ -psi_soil ppfd vpd layers psi_stem opt_root_psi ci assim transpiration gc profit e_up uptake -0.5 100 0.5 1 1.4064315157230882 1.1397291800324882 33.535719423557353 3.4216414573490117 7.9644452142332409e-06 0.053619621786311598 3.3030570555526011 7.9644455320981397e-06 0.00044210077891191453 -0.5 100 0.5 3 1.5954124971659938 1.4018117298270372 31.191249087006778 3.2939585898339492 5.626586940336478e-06 0.037880286143406806 3.1008759409911337 5.6265870700498372e-06 0.00031232789731056547 -0.5 100 0.5 5 1.7452545545113238 1.5881353349338942 29.262213724659755 3.1770775521522618 4.4519911133823881e-06 0.029972468046986948 2.9051006149550638 4.4519915504116376e-06 0.00024712692480775118 -0.5 100 1 1 1.5932824843611644 1.2671223542432735 29.879407846846796 3.2157448245139046 9.5619590523274174e-06 0.032187340996817596 3.023650171377644 9.5619591422393007e-06 0.00053077763764858732 -0.5 100 1 3 1.7920899362273437 1.5523575254639288 26.688926403109683 3.0013314142961085 6.7853474838497329e-06 0.022840747596739566 2.7006930858511775 6.7853474843817848e-06 0.00037664987423712378 -0.5 100 1 5 1.9404992363787317 1.7453156059561379 24.22920998828554 2.8076762493713701 5.3575323613880757e-06 0.018034455081201134 2.402599334908301 5.357532576432653e-06 0.00029739287129795463 -0.5 100 2 1 1.7967548832244611 1.4030643672663468 24.763245420986252 2.8521396964186123 1.1266254056967917e-05 0.018962158230542741 2.5485370769014066 1.126625410728482e-05 0.000625381854414922 -0.5 100 2 3 1.974750501718451 1.6895987603563785 20.874909545225634 2.4917019650291854 7.8414037562845282e-06 0.013197815176578424 2.0594485162722274 7.8414043294004221e-06 0.00043527084814878831 -0.5 100 2 5 2.0812347115368164 1.8568575136921954 18.155583441976756 2.1776498358393557 5.9999663789796766e-06 0.010098504017471864 1.6531924903518367 5.9999667351424357e-06 0.00033305394033541135 -0.5 100 4 1 1.9478356888215389 1.5017496970624489 18.554034088544238 2.22758211566109 1.2503146687341704e-05 0.010521982047725396 1.8167837670905369 1.2503147133216513e-05 0.00069404091774723914 -0.5 100 4 3 2.0130156381644118 1.7179877325704682 14.788296988437251 1.6880916255969947 8.0598145297856256e-06 0.0067827104577008772 1.2240623501463719 8.0598148848335275e-06 0.00044739466471460052 -0.5 100 4 5 2.0063215670071219 1.7976840658200521 12.604399811198828 1.2879603966247419 5.6591721458135337e-06 0.0047624577406199832 0.82959875184286114 5.6591722813330852e-06 0.00031413667950780377 -0.5 500 0.5 1 2.4109901172055332 1.7891385804115791 26.953803399175349 13.96235023623394 1.6103335350584414e-05 0.10841367198476044 13.074476999673427 1.610333535121711e-05 0.00089388483770286482 -0.5 500 0.5 3 2.7164829891259941 2.210510814002963 23.551280527047581 12.950185456809166 1.1846365343788493e-05 0.079754158913824647 11.617786198957624 1.1846366710650622e-05 0.00065758349767697038 -0.5 500 0.5 5 2.9416567539754097 2.4917986705441106 21.156049380602255 12.089414780959613 9.6532721227130728e-06 0.064989435710501212 10.366287275475118 9.6532733143316879e-06 0.00053584642322129826 -0.5 500 1 1 2.7771547107039529 1.9960803050999476 20.778763228621415 11.939993582679428 1.8693644905798969e-05 0.06292630200188086 10.507323310430499 1.8693645986015445e-05 0.0010376711621435163 -0.5 500 1 3 3.0330102014270279 2.4086469007774403 17.044362096255803 10.197210725093214 1.3367901976215948e-05 0.044998856088571453 8.3018317586369506 1.3367901981828912e-05 0.00074204285216924299 -0.5 500 1 5 3.158329436174887 2.6343326757148198 14.72304159230254 8.7962094107062914 1.0472297472006299e-05 0.035251710230816372 6.6531341193001641 1.0472298027026705e-05 0.00058130990990989202 -0.5 500 2 1 2.9462904096973768 2.0844428808493811 14.248433530867084 8.4712366920423499 1.9799051423878981e-05 0.033323653453567317 6.73955249947117 1.979905230028143e-05 0.0010990314904402681 -0.5 500 2 3 2.9225815548173313 2.341499812224078 11.30988163184572 6.1265377221242154 1.2852392837172094e-05 0.021631777997126112 4.4384260644956619 1.2852394389878225e-05 0.00071342738772568553 -0.5 500 2 5 2.8331109150616167 2.4173177253909577 9.7364229966751275 4.6386409369409947 9.2251134932391925e-06 0.015526727949590972 3.1101510785484425 9.2251137575675636e-06 0.00051207958687580146 -0.5 500 4 1 2.6402150326898228 1.9210741314244792 9.583691352196416 4.4863829806344775 1.7755015392816997e-05 0.014941674915279099 3.2745250391091165 1.7755016415853437e-05 0.00098556849380257764 -0.5 500 4 3 2.436356190059195 2.0218974856044101 7.9399765537701912 2.7690999438141009 1.039695131715295e-05 0.0087495202484437189 1.8482539356547498 1.0396952294769349e-05 0.00057712752121950308 -0.5 500 4 5 2.2867611239124623 2.0165836351964481 7.1431380235951307 1.8887638024633597 6.9196285659173781e-06 0.0058231907029629715 1.1519511946939347 6.9196289469184526e-06 0.00038410374393108259 -0.5 900 0.5 1 2.7197604410447296 1.9650087070302305 26.048188942300413 16.972876943369247 1.8304847057311886e-05 0.12323507157978909 15.635159184548764 1.8304848479194313e-05 0.0010160892855506142 -0.5 900 0.5 3 3.0590453936785376 2.4241509568610997 22.789749720102563 15.426180066088692 1.3486909354637156e-05 0.090798914326078783 13.480384375876335 1.3486910990082746e-05 0.00074864895865016639 -0.5 900 0.5 5 3.2874061407846096 2.7150123329803253 20.561732192903435 14.127399787118666 1.0935682742199681e-05 0.073623103284576094 11.717131613072423 1.0935684088448819e-05 0.00060703214479316235 -0.5 900 1 1 3.0845830084812627 2.1529681238294636 19.97225367517332 13.746976172967521 2.0656004615744774e-05 0.069531971488309738 11.751181815336844 2.0656005529640243e-05 0.0011466003624557449 -0.5 900 1 3 3.2552167071314448 2.5367564606412776 16.514782254357918 11.199702974192943 1.435103216180415e-05 0.048308256009091888 8.8571004956490924 1.4351033237008327e-05 0.00079661577779674311 -0.5 900 1 5 3.3008316449748913 2.7232113254639621 14.362616300819928 9.3565169518213231 1.0982765970949394e-05 0.036970042588620779 6.9178393586801477 1.098276621059857e-05 0.00060964564033297644 -0.5 900 2 1 3.0506148929043064 2.1364568870268736 13.845359547567909 8.8865087986354219 2.0449544585256871e-05 0.034418494222430041 6.9571008272649895 2.0449545713341029e-05 0.0011351399230275342 -0.5 900 2 3 2.9571261757000715 2.3627422523318664 11.116998278664372 6.2459967177706446 1.3015493666290431e-05 0.021906291931716625 4.4942259627744088 1.3015493821534228e-05 0.00072248092264969347 -0.5 900 2 5 2.8486017197899756 2.4280650238119645 9.6208634276290592 4.6875406037722005 9.2869014270008387e-06 0.015630722815213764 3.1319705838605385 9.2869027021054791e-06 0.00051550944779936046 -0.5 900 4 1 2.6522498945103816 1.9277849481905902 9.4686138378274389 4.5246599673937009 1.7839005529437774e-05 0.015012356539018229 3.2941949963470161 1.7839006888533584e-05 0.00099023074596356277 -0.5 900 4 3 2.4404897779943857 2.024760580173147 7.8817725565408985 2.779999416306842 1.0418959521537938e-05 0.0087680411805924202 1.8537118747795414 1.0418960614863627e-05 0.00057834918761385666 -0.5 900 4 5 2.2889167997028066 2.0182367568796988 7.104156810751137 1.8936052214909669 6.9291447675928974e-06 0.0058311990312419418 1.1543186116999431 6.9291452468913483e-06 0.00038463198706030244 -0.5 1500 0.5 1 2.8799224461320576 2.0503524385318008 25.954225797283243 18.083941475864044 1.9372632441163001e-05 0.13042380185427568 16.472899690884777 1.9372633102666599e-05 0.0010753612602090812 -0.5 1500 0.5 3 3.1949269863757976 2.5029592249071397 22.736487599463157 16.167837514687879 1.4091719930031613e-05 0.09487072515943816 13.950159453241419 1.4091721595786878e-05 0.00078222157067926051 -0.5 1500 0.5 5 3.3913677928808559 2.7775205859597101 20.515385285153567 14.625846867062334 1.1294588890250277e-05 0.076039393609589986 11.992938265924771 1.129458987745448e-05 0.00062695475311987125 -0.5 1500 1 1 3.1648920581658313 2.1911568882113492 19.864151222823185 14.140651868278095 2.1133465216675298e-05 0.071139193093275252 11.984270231861251 2.1133465338826824e-05 0.0011731038211949389 -0.5 1500 1 3 3.2906228580062979 2.5562593578329533 16.43739000070611 11.353759436344893 1.4500651566868332e-05 0.04881190288565633 8.9366942855090166 1.4500652643976951e-05 0.00080492104601592848 -0.5 1500 1 5 3.3195393624445213 2.7345742020513639 14.306787609947037 9.4325989070944978 1.1048013206774189e-05 0.0371896769770447 6.9541571676104139 1.1048013895297038e-05 0.00061326749349414585 -0.5 1500 2 1 3.0635838197967802 2.1427857609299483 13.785500844902149 8.9413159162123073 2.0528683289706206e-05 0.034551692056274411 6.9866737496745239 2.052868505482719e-05 0.0011395328923023698 -0.5 1500 2 3 2.9618081449919753 2.3656048925914748 11.084785084920613 6.2635218577554408 1.3037472107710882e-05 0.021943283702163831 4.5030388889266275 1.3037472113595314e-05 0.00072370092220900998 -0.5 1500 2 5 2.8510249480242815 2.4297427398960556 9.5996738299495945 4.695682014732073 9.2965467100300613e-06 0.015646956727750592 3.1358544373266799 9.2965480996743051e-06 0.00051604485704547908 -0.5 1500 4 1 2.6541517578136102 1.9288433975318224 9.4474987045381411 4.5311514478798482 1.785225255726609e-05 0.015023504531798029 3.2977317198105895 1.7852253912286929e-05 0.00099096607895014874 -0.5 1500 4 3 2.4412643230160742 2.0252968123574115 7.8698230574427983 2.782133934042252 1.0423081447688339e-05 0.0087715099740122773 1.8548246360396572 1.042308255613048e-05 0.00057857799367918292 -0.5 1500 4 5 2.289354797741475 2.0185725843241862 7.0957185814138359 1.8946193961025655 6.9310779545242413e-06 0.0058328258983574889 1.1548294759867179 6.9310784537894314e-06 0.00038473929801773141 -1 100 0.5 1 1.7067677422675573 1.4930281707158857 31.814968089542472 3.3293694751750693 6.1204428183868747e-06 0.041205108486422753 3.079478616621798 6.120443067641477e-06 0.00033974149695484193 -1 100 0.5 3 1.908653295271608 1.7475302694978256 29.229694115283259 3.1750053074436546 4.4356538379267522e-06 0.029862479402783016 2.7941409877644108 4.4356542987663469e-06 0.00024622005544081861 -1 100 0.5 5 2.068375804921013 1.934230807726961 27.174431901929609 3.0364186889892033 3.562265404120197e-06 0.023982502049237363 2.5237264989860471 3.5622654081506123e-06 0.00019773885140997015 -1 100 1 1 1.8835359299507122 1.6113739326199386 27.806772699616921 3.0807188758916921 7.6033437173373366e-06 0.025594275776194522 2.7182450053465459 7.6033442457142131e-06 0.0004220563000674001 -1 100 1 3 2.0885287736046294 1.8829566223176897 24.465021351498685 2.8274862180378979 5.4772310308385439e-06 0.018437383170453913 2.296277123205523 5.4772316440867064e-06 0.00030403728249162954 -1 100 1 5 2.2388019480971684 2.0692951954928329 21.960274612874279 2.6015049297934909 4.3397624225280723e-06 0.014608451278097276 1.9183960334204448 4.3397633766499712e-06 0.00024089721768803617 -1 100 2 1 2.065761371813625 1.7305459556739704 22.465479553262767 2.6500079481123886 9.096084858167948e-06 0.015309560701087582 2.1396863753071385 9.0960848615259338e-06 0.00050491728345966884 -1 100 2 3 2.229326921845507 1.9869199694248711 18.593144050229022 2.2324047126725732 6.2765539131840105e-06 0.010564026680253866 1.5596038030372326 6.2765547148437753e-06 0.00034840714487059535 -1 100 2 5 2.3160596725377869 2.1296644210692173 15.953774192781461 1.8726535534532811 4.6871811403286466e-06 0.0078889638018732507 1.1017719369442722 4.6871820554767758e-06 0.00026018218459488069 -1 100 4 1 2.1570011067485102 1.7889790884374803 16.347339656953643 1.9311024117334257 9.8278048966268909e-06 0.0082705569467202249 1.3337288228517736 9.8278055398232398e-06 0.00054553458450309412 -1 100 4 3 2.172736320311301 1.9453684013868573 12.876814755737477 1.3422870152503665 5.9571140410287759e-06 0.0050131897644147541 0.7289913010853516 5.957114924354615e-06 0.00033067526640880463 -1 100 4 5 2.1290557326235366 1.9826006659667021 10.954293541487257 0.92675631179459028 3.8407392511293916e-06 0.0032321615078939612 0.35699674854767616 3.840739357933232e-06 0.00021319674482005174 -1 500 0.5 1 2.7152256348729877 2.1241858001256579 25.464804436225535 13.545571354735634 1.402224907889137e-05 0.094403021425767411 12.215209474738369 1.4022250411574108e-05 0.00077836527402576231 -1 500 0.5 3 3.035805875669717 2.5343813119374463 22.121162872843342 12.453593419118651 1.0480853321201807e-05 0.070561021636050256 10.552828035611192 1.0480853402337577e-05 0.00058178481278587713 -1 500 0.5 5 3.2714972563656546 2.8125569558448102 19.829090633916422 11.544687301949235 8.6118791039231962e-06 0.05797838870139773 9.167942008783232 8.6118810868372665e-06 0.00047803947193101676 -1 500 1 1 3.0692158668619798 2.3123650617248628 19.251243270473637 11.28963717944057 1.6374163783621359e-05 0.055118495107221555 9.3239932073480407 1.6374165540780969e-05 0.00090891843135059499 -1 500 1 3 3.3073938746229428 2.6945336682085506 15.732686650722133 9.4420256633549435 1.1708862404537072e-05 0.039414218868456571 6.9894229362945355 1.1708862402854945e-05 0.00064995073010574219 -1 500 1 5 3.4070871781761753 2.8968799833242369 13.576633462760762 7.9864201400500843 9.0956811562017521e-06 0.03061776246591786 5.3193551702314501 9.0956832275089874e-06 0.0005048949890374126 -1 500 2 1 3.1413635735369425 2.3480117351669367 12.999010208695836 7.5455276369579689 1.6819425171713963e-05 0.028308664072381824 5.4367043667830455 1.6819426904326606e-05 0.00093363457698177109 -1 500 2 3 3.062141766165432 2.5505311945440359 10.338947585502243 5.2261867652917946 1.0604729349280254e-05 0.017848750338517717 3.2743573499459844 1.0604731085965469e-05 0.00058866117601806653 -1 500 2 5 2.9434589272259224 2.593903629993414 8.9104733396616336 3.7999726760580361 7.3564380737870968e-06 0.012381572620587781 2.073519555117354 7.3564391483246717e-06 0.00040835077148624325 -1 500 4 1 2.7261277399387702 2.1302922749371764 8.773502327045108 3.6573638213630395 1.4098603690961561e-05 0.011864633651341433 2.3092812369319966 1.4098605073228007e-05 0.0007826036676784905 -1 500 4 3 2.4954622287011667 2.1775680412556895 7.3327904819707905 2.1009467196346536 7.7416621761021547e-06 0.0065149703889317732 1.1004735807472374 7.7416627394189056e-06 0.0004297342625267225 -1 500 4 5 2.3314278361602039 2.1416036255756463 6.6399870006979089 1.3180326577846722 4.7558831455861534e-06 0.0040022978479169226 0.5288968274739948 4.7558834491892204e-06 0.00026399575071824706 -1 900 0.5 1 3.0369913612965367 2.2961354722933662 24.742429827264274 16.398047102611969 1.6171413488520494e-05 0.10887199945263296 14.494995645437719 1.6171413622583404e-05 0.00089766381474234828 -1 900 0.5 3 3.3865464507156968 2.7384158494852802 21.578426575077408 14.746811577469545 1.2045161796821869e-05 0.081092530933141255 12.124355120461686 1.2045162333402272e-05 0.00066861850310309591 -1 900 0.5 5 3.6170247196088368 3.0196356678278651 19.440314062236823 13.390099586425803 9.7996047382133619e-06 0.065974601567892657 10.257496764667584 9.7996070277024083e-06 0.00054396930489605377 -1 900 1 1 3.3576561041771913 2.4489754226298484 18.643176569034416 12.83115003746013 1.8080071770368084e-05 0.060860900170674165 10.271078878653658 1.8080073047062817e-05 0.0010036121591486438 -1 900 1 3 3.4939022296603972 2.7957986590234949 15.351061741426308 10.226068716717712 1.248480356792383e-05 0.042026181823194148 7.3683871871339859 1.2484805059482584e-05 0.00069302276211393745 -1 900 1 5 3.5175050865725619 2.9626679840723025 13.319678229798109 8.3986029508113393 9.4729928860268937e-06 0.031887864256097027 5.4885831070771083 9.4729929558933188e-06 0.00052583918711592112 -1 900 2 1 3.2141137764500574 2.3829721951774081 12.713361318629971 7.8232946939695225 1.7256029291685077e-05 0.02904350960002007 5.5661264432551079 1.7256030895840091e-05 0.00095787015797058517 -1 900 2 3 3.0850088484570333 2.5644496204877036 10.202963924130579 5.3029982091841674 1.0711483748788707e-05 0.01802842796739507 3.3063656271131698 1.0711484629114369e-05 0.0005945869902367121 -1 900 2 5 2.9537152220507399 2.601027572464881 8.8284794052283146 3.8311895802719165 7.3973620357422593e-06 0.012450451472253172 2.0857533745107304 7.397362385864237e-06 0.00041062239166606923 -1 900 4 1 2.7339377312023632 2.1346552593160761 8.6916421140633435 3.6811405151422663 1.415315689711806e-05 0.011910542722887853 2.3202866368106414 1.4153157986835286e-05 0.00078563186160617742 -1 900 4 3 2.4982141815821537 2.1794945706983837 7.2903162841984859 2.1077000742102197 7.7564622167500938e-06 0.0065274253145514872 1.1034243993060164 7.756462928719499e-06 0.00043055581064221476 -1 900 4 5 2.3328579649223835 2.1427134553086864 6.6112464997307274 1.3209395530578538 4.7622693365955081e-06 0.0040076721259954002 0.53009157560945619 4.7622695795766041e-06 0.0002643502403317571 -1 1500 0.5 1 3.1922321281105304 2.3725620315680356 24.718912385147345 17.392810431699328 1.7126031006807495e-05 0.11529884136117691 15.18065839014611 1.7126032506810799e-05 0.00095065403867947824 -1 1500 0.5 3 3.5096072720630076 2.8039824620169203 21.562678360526306 15.374946328460103 1.2547494229338257e-05 0.084474420608820294 12.482461499737438 1.2547494363246552e-05 0.00069650260134590915 -1 1500 0.5 5 3.7077555968398088 3.0695766904607504 19.415464149517739 13.797877140788749 1.0085848099201465e-05 0.067901698853664164 10.460422636202752 1.0085848982686199e-05 0.00055985839482021644 -1 1500 1 1 3.4204858310939494 2.4765947659114316 18.560857698339614 13.126198050673592 1.8424799466556563e-05 0.062021318014710544 10.429927136724768 1.8424801254322564e-05 0.0010227477798680302 -1 1500 1 3 3.5205658442244991 2.8096606660018448 15.291513696850064 10.337957445055922 1.2590988395402126e-05 0.042383619795060404 7.4211362390016227 1.2590988643793438e-05 0.00069891693831770408 -1 1500 1 5 3.5317723269039187 2.9709726723850061 13.277169491194476 8.4542692824670933 9.5206114979305644e-06 0.032048157402172102 5.5125192302727708 9.5206127987523838e-06 0.00052848253115472571 -1 1500 2 1 3.2232424539819684 2.3872881801530794 12.668411979997003 7.8606563820005171 1.7309924190410612e-05 0.029134219750198215 5.5846108764109701 1.7309925102441205e-05 0.00096086178753489898 -1 1500 2 3 3.0883892201068082 2.5664988442623313 10.178702088130448 5.3151035915638616 1.0727200836060113e-05 0.018054881293785251 3.3118119009813518 1.0727201449678981e-05 0.00059545941991001833 -1 1500 2 5 2.9554596970564115 2.6022375437705394 8.8125274152766586 3.8367518445415016 7.4043126539915635e-06 0.012462150012191732 2.0880772646025503 7.4043128977633453e-06 0.0004110082097009906 -1 1500 4 1 2.7352812917992591 2.1354048537076493 8.6757067600129023 3.6854531281240157 1.4162529467508085e-05 0.011918430178730047 2.322395761012662 1.4162530485401433e-05 0.00078615212242028499 -1 1500 4 3 2.4987631019842627 2.1798787295983111 7.2812223862232885 2.1090882162638973 7.7594134017956244e-06 0.0065299088746380079 1.1040530552521008 7.7594141425531943e-06 0.00043071963044980259 -1 1500 4 5 2.3331635051203539 2.1429505383645338 6.6048151108982829 1.3215724696996087 4.7636335585048049e-06 0.0040088201824645181 0.53035840317157845 4.7636337889766626e-06 0.00026442596663761657 -2 100 0.5 1 2.4704409560027627 2.3109040793539894 27.864790208576487 3.0847067213104089 3.824791973188767e-06 0.025749929027975127 2.1184190402609073 3.8247922595087756e-06 0.00021231153258444496 -2 100 0.5 3 2.6821993311383823 2.5512710143277415 25.127782290595782 2.8816849389225179 2.9154929167692038e-06 0.019628187941887327 1.6042391526372659 2.9154930173534269e-06 0.00016183697015561627 -2 100 0.5 5 2.8509855879492738 2.735486416901832 23.085569152493164 2.7074341653496146 2.4084727913981762e-06 0.01621473896594882 1.1476757888076996 2.4084741793784216e-06 0.00013369271048450855 -2 100 1 1 2.6100156394027958 2.397790170751485 23.291015323167962 2.7259697192257728 4.9095556873461843e-06 0.016526481883752976 1.5601118072929787 4.9095559196940243e-06 0.00027252600164829444 -2 100 1 3 2.8082784927398938 2.6402594720555435 19.973239446667055 2.3941655506633768 3.5976150896033781e-06 0.01211024467168941 0.90858838838593825 3.5976159030017058e-06 0.00019970113255629785 -2 100 1 5 2.9480523443568321 2.8079203768044358 17.584829690510492 2.1034901218696693 2.8240322880430286e-06 0.0095062204035624917 0.36854709614734471 2.82403303634158e-06 0.00015676009083217209 -2 100 2 1 2.712595930747344 2.4599365619557996 17.64556056679524 2.1115336906467768 5.6850652148631124e-06 0.009568495935746834 0.78542751852611947 5.6850664542705428e-06 0.00031557404686486501 -2 100 2 3 2.8117431942213011 2.6426730270030294 14.040344791445145 1.5596941651672354 3.6161109500043962e-06 0.0060862525970442755 0.068166761765579231 3.616111532962547e-06 0.00020072781198792933 -2 100 2 5 2.8304537502797467 2.719997127712662 11.674770130440052 1.0916494104229488 2.3195885757322019e-06 0.0039040843017018553 -0.43221921738695168 2.3195887026395502e-06 0.00012875874008545936 -2 100 4 1 2.6076015233890186 2.3963096166450253 11.903653325502439 1.1416239167871969 4.8910761097506907e-06 0.0041160690430799918 -0.020599632298418102 4.8910764658744304e-06 0.00027150022014290481 -2 100 4 3 2.4903264302105312 2.4118727410394039 9.2084082334114274 0.47228012178541023 1.8462850009310341e-06 0.0015537350813014652 -0.52111917684090359 1.8462852906314161e-06 0.00010248600003504946 -2 100 4 5 2.362181249757271 2.3533606344612839 7.8634321681794095 0.057021658155842037 2.1358540125426123e-07 0.00017974209323871968 -0.7694374281382208 2.1358611617419419e-07 1.1856015330235592e-05 -2 500 0.5 1 3.4819575298678949 2.8696986466766958 22.461253229084171 12.576122885280533 1.0789204948889131e-05 0.072636960035907736 9.744850709349052 1.0789207105251822e-05 0.00059890131031095325 -2 500 0.5 3 3.8395770305726988 3.2612194505212155 19.469718513045258 11.387429236689602 8.3458776851062885e-06 0.056187567735475882 7.7510281358166164 8.3458792359561454e-06 0.00046327389597314159 -2 500 0.5 5 4.1100266689605318 3.5360870702229903 17.513011346189415 10.446487742119256 6.9900491021178888e-06 0.047059622992132226 6.202819001663201 6.9900512255430665e-06 0.00038801283516753075 -2 500 1 1 3.7816796621496387 2.9978937235432248 16.271832091163958 9.7632232603743709 1.2382269085228115e-05 0.041681031593999648 6.258169554746102 1.2382269495624353e-05 0.00068733108496388305 -2 500 1 3 3.9593833143631572 3.318190783682232 13.311529166708752 7.7868653503434366 8.7803170485033981e-06 0.029556187947862033 3.8795338797563659 8.7803195330332478e-06 0.00048738937180312233 -2 500 1 5 3.9981502429048379 3.4796062195553077 11.517143349619399 6.3109370845151229 6.6677841192955336e-06 0.022445007342788349 2.3164561766601923 6.66778413464234e-06 0.00037012401524520342 -2 500 2 1 3.5651786682825946 2.9071999644587345 10.621286290709744 5.4940657159362551 1.1255435207671125e-05 0.018943949096326448 2.4777684113847736 1.1255436519412007e-05 0.00062478137770813249 -2 500 2 3 3.3789229920756125 3.0105977683443332 8.4971557653818728 3.3667082756022455 6.4321615003289102e-06 0.010825928788478528 0.76075508296540262 6.432161538890734e-06 0.00035704477040747901 -2 500 2 5 3.198688118828958 2.9882494321805666 7.3267885336594123 2.0942568071790348 3.8577966509517737e-06 0.0064930322134323327 -0.1311422695237896 3.8577984840195662e-06 0.00021414368493031177 -2 500 4 1 2.9193741078636553 2.5803514250031343 7.204849352922424 1.9579853501404143 7.1867249367511624e-06 0.00604796477697835 0.27572823838314386 7.1867263640706507e-06 0.0003989301340033667 -2 500 4 3 2.6291525126438855 2.5131871721753614 6.1383480404337547 0.7379923310491594 2.6234628729014484e-06 0.002207766568034405 -0.45690009670396314 2.6234632522882945e-06 0.00014562660295799581 -2 500 4 5 2.4309429891018746 2.4085954956345947 5.6403935829542213 0.15159583021147194 5.3109264939455165e-07 0.00044693927555579914 -0.76215310850824491 5.3109340144785139e-07 2.9480621784504654e-05 -2 900 0.5 1 3.8400913328934534 3.0206380684959999 22.113761267636939 15.054715889153814 1.2664695987234463e-05 0.085263466645555494 11.417148519612585 1.2664697485989271e-05 0.00070300846439018991 -2 900 0.5 3 4.2155296484543321 3.4279871005681599 19.252128048114827 13.260753280719838 9.6169169198817091e-06 0.064744678897773231 8.7863422413163033 9.6169178233486787e-06 0.00053382835544538881 -2 900 0.5 5 4.4671370807611188 3.6938373088280572 17.359386275876343 11.870832180526506 7.8892223865953806e-06 0.053113193597135171 6.8700173900688819 7.8892232078936594e-06 0.00043792524051588453 -2 900 1 1 4.0087136466677755 3.0821516859478084 15.947993489155504 10.732430623985156 1.3428206183219658e-05 0.045201851318288383 6.7142641994308896 1.3428207050937252e-05 0.00074539034420967256 -2 900 1 3 4.0766946476387895 3.3705219524662304 13.110722600481111 8.2018404319118865 9.1791698954489036e-06 0.030898801163619496 4.0319955655499973 9.1791706681837173e-06 0.00050952931824500239 -2 900 1 5 4.0612083310013345 3.511847824527802 11.383486050822826 6.5155059423715898 6.8517678846531879e-06 0.023064331077708954 2.3800899622217413 6.8517680189574251e-06 0.00038033683147140854 -2 900 2 1 3.5950876308832083 2.9203230867281595 10.487044292254941 5.5991531654660385 1.1418547459418835e-05 0.019218482256269463 2.5158434915102319 1.1418548219811386e-05 0.00063383559366147026 -2 900 2 3 3.3882916202523394 3.0161645842149234 8.4330807942121737 3.3958725913161429 6.4747113015510934e-06 0.010897544079539195 0.7696341207654056 6.4747119968288725e-06 0.00035940671644900765 -2 900 2 5 3.2028165788824521 2.9911313493716256 7.2885559865986647 2.1056812201890178 3.8743078577051985e-06 0.0065208221171086126 -0.12820430355900836 3.8743097759752016e-06 0.00021506021515266176 -2 900 4 1 2.9222895808709417 2.5819998646394193 7.166865607347205 1.9658577398729884 7.2072727491900629e-06 0.0060652567210791918 0.27827941998063221 7.2072742925656951e-06 0.00040007073508552292 -2 900 4 3 2.6301268350610636 2.5138899336647542 6.1184384215655232 0.73994318226054379 2.6288522000538545e-06 0.0022123019386067065 -0.45643814171370156 2.6288526364490237e-06 0.00014592576388837211 -2 900 4 5 2.4313786076646746 2.4089440918230176 5.6271233468864565 0.15222650441552532 5.3309622897031711e-07 0.00044862538137016475 -0.76209234372015866 5.3309700155554493e-07 2.959184021956952e-05 -2 1500 0.5 1 3.9803812658593372 3.0722462266911599 22.154006949312173 15.78061470379628 1.3305292457998546e-05 0.089576201501039454 11.826037199126354 1.330529373406011e-05 0.00073856751229864608 -2 1500 0.5 3 4.3157965927420481 3.4664693846305616 19.247513520586818 13.6678115734312 9.9099182435240381e-06 0.066717273313830469 8.9790918596189435 9.9099204815103372e-06 0.00055009272725563903 -2 1500 0.5 5 4.539487477635439 3.7215752567027653 17.335640714614101 12.12121336341187 8.0471830062666055e-06 0.054176643524415244 6.9767843417955504 8.0471834659582436e-06 0.00044669350352252257 -2 1500 1 1 4.0443287814229798 3.0943574999267689 15.894511443475128 10.877600995328757 1.3579644797175919e-05 0.045711621991935972 6.7797983420985535 1.3579646613004726e-05 0.0007537966479602956 -2 1500 1 3 4.0921737820958475 3.3771694416063567 13.074744689859084 8.258131398878831 9.2298189627766387e-06 0.031069295388947912 4.0539542774071071 9.2298212946844988e-06 0.00051234089895556474 -2 1500 1 5 4.069914831589597 3.5162171193496432 11.358394947369653 6.5449449381217217 6.8766966891728971e-06 0.023148246092124704 2.3901631425650685 6.8766968339467918e-06 0.00038172061248663844 -2 1500 2 1 3.599439433657535 2.9222168031323053 10.462878037850402 5.6152881633934335 1.1442082939030142e-05 0.019258094667472393 2.5222089124548823 1.1442084147087298e-05 0.00063514205645780176 -2 1500 2 3 3.3899632735757614 3.0171559482354615 8.4201371739503887 3.4012407792525292 6.4822885296522992e-06 0.010910297262405253 0.77137820461729234 6.4822893827223713e-06 0.00035982733181917132 -2 1500 2 5 3.2036437587982807 2.9917084046253093 7.2802879741231701 2.1080107398202292 3.8776139227280708e-06 0.0065263865334414233 -0.12757655630205411 3.877615844945832e-06 0.00021524373271972422 -2 1500 4 1 2.9228794904180022 2.5823332322536849 7.1586329598464111 1.9674843762769045 7.2114281525988563e-06 0.006068753687175946 0.2788284088127011 7.2114297143772245e-06 0.00040030139963237438 -2 1500 4 3 2.630345725825717 2.514047799134147 6.1138366389006169 0.74038448443308091 2.6300628334363238e-06 0.0022133207431552933 -0.4563314758904724 2.6300632828359978e-06 0.0001459929660192061 -2 1500 4 5 2.4314815681278636 2.4090264816395592 5.6239655893117853 0.15237572180820846 5.3356976947499669e-07 0.00044902388782727556 -0.76207785814843199 5.3357054686414518e-07 2.9618126387129905e-05 -3 100 0.5 1 3.3894032063216408 3.2245052025538747 24.395376810110989 2.8216649025452747 2.7207796984814003e-06 0.018317305784931882 0.19301669354489448 2.7207804983011643e-06 0.00015102861494871854 -3 100 0.5 3 3.6058183243270427 3.4569133888498467 21.965340136022029 2.6019991807901666 2.1709030453066028e-06 0.014615330646768537 -0.50540858674934963 2.170904846423881e-06 0.00012050540363163369 -3 100 0.5 5 3.7828784911723914 3.6413779563211923 20.256286022347489 2.4254372519838294 1.848427499209952e-06 0.012444304749555263 -1.0823364562504527 1.8484278099483304e-06 0.00010260492977787013 -3 100 1 1 3.4919712238890019 3.2781663236001766 19.346535968457804 2.3226814269278209 3.3842930994222709e-06 0.011392162989629936 -0.53072708180788064 3.3842947506628704e-06 0.00018785982518250739 -3 100 1 3 3.6736771812209419 3.4978767114442935 16.434188869341043 1.9437542056510844 2.4821623124058188e-06 0.0083554221809189633 -1.3166050041277551 2.4821640663327993e-06 0.00013778318436485148 -3 100 1 5 3.7984887317106959 3.6514232103499729 14.393865899085538 1.6214166636735459 1.9055565447079289e-06 0.0064144594175293479 -1.9217758768375748 1.9055570150683615e-06 0.00010577613183837699 -3 100 2 1 3.4687248925417826 3.2661982843419288 13.348160303815607 1.4331194765225499 3.2363570231902759e-06 0.005447091256237685 -1.3689598101589016 3.2363587880728021e-06 0.00017964800377867344 -3 100 2 3 3.4661293132423152 3.3693394982157336 10.215758390722575 0.74472064563344142 1.504901472614064e-06 0.0025328897875719122 -2.0516405866507448 1.5049030334351141e-06 8.3536110654183415e-05 -3 100 2 5 3.3879847023515448 3.3692298143457196 8.1701879821943226 0.15754211678273911 2.9789541733650987e-07 0.00050138582097701318 -2.468031112893958 2.9789608413502247e-07 1.6536002449904106e-05 -3 100 4 1 3.0587357978664129 3.0372799024756612 8.0137425520274697 0.10673619974829762 4.0167936598268576e-07 0.00033803195175582858 -1.8384566349724119 4.0168098842366742e-07 2.2297029609973212e-05 -3 100 4 3 3.1718079687688916 3.1718075251234743 7.6943188555106987 2.1029354733137495e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704362845848699 7.8605668043621887e-12 4.3633454367816762e-10 -3 100 4 5 3.3170442487608387 3.3170439012574113 7.6943171755844508 1.5306961840266808e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731250224273484 6.1738007589111003e-12 3.4270334492984183e-10 -3 500 0.5 1 4.5555449297032249 3.6945550278102952 19.69550030743509 11.486742857939404 8.5122787015784824e-06 0.057307841568504672 6.3109739407587977 8.5122791194975708e-06 0.00047251063666375637 -3 500 0.5 3 5.019011136114008 4.0642255866232802 17.169576317069865 10.264808786022385 6.7651607547216718e-06 0.045545590588470991 4.2797884468497616 6.7651614474186194e-06 0.00037552936149978458 -3 500 0.5 5 5.401274999154448 4.3244488262832501 15.50351450134565 9.3006482910306243 5.7128216916137531e-06 0.038460850718081876 2.8011060012251487 5.7128236367345905e-06 0.00031711482857255569 -3 500 1 1 4.7226064225088908 3.736698384461282 13.520658263929683 7.9446780912020216 9.0290143691780389e-06 0.030393349602889318 2.4552127559125809 9.0290169108722415e-06 0.00050119438861350222 -3 500 1 3 4.818006888517318 4.0098279512101929 11.249249197695573 6.0720636190989605 6.3556261997680679e-06 0.021394225453250551 0.41423067585717366 6.3556264065340221e-06 0.00035279635895276281 -3 500 1 5 4.8169823166297228 4.1629844925990511 9.9037470591463332 4.8039251878274207 4.803469430406891e-06 0.016169375718740699 -0.8521431404228581 4.8034697136861792e-06 0.0002666372308457496 -3 500 2 1 4.0665427978557656 3.535578507666441 8.5540935181107169 3.4269115472412435 6.5590357187639538e-06 0.011039469952487146 -0.72037277251076182 6.5590357235393206e-06 0.00036408746730720625 -3 500 2 3 3.7893776749063957 3.5652129601639646 6.9269447245470896 1.6449101307943037 2.9934298030041625e-06 0.005038222046970563 -1.8776097534579179 2.9934298027090635e-06 0.00016616318638407236 -3 500 2 5 3.538251302398741 3.4766523548650303 5.948069739794434 0.51515468472516734 9.1053603490881845e-07 0.0015325172218953779 -2.4410265380679164 9.1053789206522982e-07 5.054331901555536e-05 -3 500 4 1 3.157309522397473 3.0952482381147961 5.7812143625577033 0.31848745187610028 1.1203634913581655e-06 0.00094283821807291833 -1.8225227120380025 1.1203641276924747e-06 6.2190626016790163e-05 -3 500 4 3 3.1718079687688916 3.1718075251234743 5.5130832403453356 2.2449228223031525e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704361425975209 7.8605668043621887e-12 4.3633454367816762e-10 -3 500 4 5 3.3170442487608387 3.3170439012574113 5.5130827284672623 1.6340505599732325e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731249190729727 6.1738007589111003e-12 3.4270334492984183e-10 -3 900 0.5 1 5.0180268979520628 3.7975432254481181 19.414320713718364 13.372329713539733 9.7742423268233092e-06 0.065803852335555274 7.3888176534234447 9.7742431207051999e-06 0.000542561372228987 -3 900 0.5 3 5.4764967900577117 4.1545432442363115 16.837175216979769 11.459480812134075 7.4441419862142164e-06 0.050116745998966122 4.8752705475890803 7.4441440500492583e-06 0.00041321920899524054 -3 900 0.5 5 5.8013296835189756 4.3899086998182701 15.142197599915233 10.045517058902471 6.0806610056497369e-06 0.040937282455159818 3.1545204535688427 6.0806616927652049e-06 0.00033753326076964779 -3 900 1 1 4.8734291863811237 3.7698435644914516 13.292840633749904 8.3734206660446588 9.4350984453695764e-06 0.03176030448757617 2.6215751874561031 9.4351000075474842e-06 0.00052373577616139243 -3 900 1 3 4.8869358839289037 4.0295932422127958 11.114453699186406 6.2434114337188404 6.5044801661743791e-06 0.021895295720256409 0.46908712873083402 6.5044803683623574e-06 0.00036105913784970068 -3 900 1 5 4.8560864385969378 4.1766471491000363 9.8160561643274171 4.895207274063889 4.880522567915532e-06 0.016428750978380788 -0.8275254869662465 4.8805250855580214e-06 0.00027091452043064235 -3 900 2 1 4.0779921658897864 3.5399325165795843 8.4925319274631992 3.4616662034496559 6.6126098969010122e-06 0.011129640299948632 -0.71105967378371071 6.6126108170789102e-06 0.00036706138312955371 -3 900 2 3 3.7930920923102871 3.5673209441121259 6.8980269783821555 1.6551466837878888 3.0094270994827301e-06 0.0050651469916374991 -1.8758010740809179 3.009427173071153e-06 0.00016705118917963659 -3 900 2 5 3.539581228930027 3.4775830854946932 5.9323935238326548 0.51839440674236137 9.1584062613583674e-07 0.0015414453445603254 -2.4407507266674298 9.1584257229544153e-07 5.0837778090227118e-05 -3 900 4 1 3.1580369882024693 3.0956695037773008 5.7667430395944201 0.32010689149219473 1.1255842805948365e-06 0.00094723175611553161 -1.8223761710063466 1.1255848587270416e-06 6.2480425130560175e-05 -3 900 4 3 3.1718079687688916 3.1718075251234743 5.501017589818554 2.2457082262672401e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704361418121172 7.8605668043621887e-12 4.3633454367816762e-10 -3 900 4 5 3.3170442487608387 3.3170439012574113 5.5010170845183026 1.6346222411200984e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731249185012913 6.1738007589111003e-12 3.4270334492984183e-10 -3 1500 0.5 1 5.1494182070134897 3.81950343693725 19.374717677881137 13.766409613076235 1.004296649777694e-05 0.067613003886453485 7.5898737808376078 1.0042967914877269e-05 0.00055747809685691195 -3 1500 0.5 3 5.5617716200243139 4.166939115283478 16.766700224328499 11.63808802082629 7.537233499108101e-06 0.05074347285546648 4.9642657164494688 7.5372347801582334e-06 0.00041838661005596633 -3 1500 0.5 5 5.8599304454265715 4.3970860580591857 15.073470699689445 10.140055961175541 6.1209631836778935e-06 0.041208611780041406 3.2032698294063202 6.1209632217806186e-06 0.00033977037034585726 -3 1500 1 1 4.8932726257930463 3.7738744591851079 13.252120821424089 8.4300661532444945 9.4844653407145964e-06 0.031926482682413521 2.6452546968187036 9.4844653415601318e-06 0.0005264760111884614 -3 1500 1 3 4.8965574159141925 4.0322584819650604 11.089254423165663 6.2681372868433538 6.524548023622489e-06 0.02196284787847242 0.4779044273706603 6.5245481501016858e-06 0.00036217308632260258 -3 1500 1 5 4.8622783264717739 4.1787705810784024 9.7989158414594417 4.9100041069109857 4.8924967491253458e-06 0.016469058309927467 -0.82315490860440033 4.8924991748363476e-06 0.00027157919371836512 -3 1500 2 1 4.0800293882451921 3.5407040219402526 8.4800117793062864 3.468013019937215 6.6221024032753374e-06 0.011145617075100712 -0.70923515871034537 6.6221035600347774e-06 0.00036758831862529988 -3 1500 2 3 3.7938681865937283 3.5677609603479135 6.8915901715481622 1.6573053843264898 3.0127662561226404e-06 0.0050707671042536694 -1.8754033063923536 3.0127663692509844e-06 0.00016723654561482011 -3 1500 2 5 3.5398865359872871 3.4777966989329334 5.9287168384284215 0.51913954723160782 9.170580842527024e-07 0.0015434944403231524 -2.4406860804586836 9.1706004934701172e-07 5.090535938645638e-05 -3 1500 4 1 3.1582065481685042 3.0957676796645961 5.7633236555203613 0.32048491920130329 1.1268009801165322e-06 0.00094825566560367022 -1.8223415071602311 1.1268015448264658e-06 6.2547962521591221e-05 -3 1500 4 3 3.1718079687688916 3.1718075251234743 5.4981265041926832 2.2458964208382781e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704361416239224 7.8605668043621887e-12 4.3633454367816762e-10 -3 1500 4 5 3.3170442487608387 3.3170439012574113 5.4981260003794903 1.6347592253218579e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731249183643071 6.1738007589111003e-12 3.4270334492984183e-10 -4 100 0.5 1 4.4459218792567778 4.1862871534264974 22.077052822713853 2.6128578273891452 2.1935502245210645e-06 0.0147677999213184 -2.3451254103878862 2.1935528367183268e-06 0.00012176257766962679 -4 100 0.5 3 4.6904578863907487 4.4215447254263003 20.274767131042225 2.4274578574618211 1.8517006890389585e-06 0.012466341086794733 -3.0034590600146451 1.8517008604983952e-06 0.00010278661451559229 -4 100 0.5 5 4.9038252494095973 4.6150013960632057 19.079594928209161 2.2912543716449512 1.6479515739015907e-06 0.011094625895203313 -3.5109376483101289 1.6479523605428227e-06 9.1476678353750914e-05 -4 100 1 1 4.5263251555693831 4.2138943451592796 16.584674486805739 1.965470692378005 2.5260247220205983e-06 0.0085030712481746276 -3.1531216166338347 2.526026621842223e-06 0.00014021796402121693 -4 100 1 3 4.7108904301553487 4.4296829714116281 14.417301773157259 1.6254417806013213 1.9120370115474528e-06 0.0064362738799047699 -3.8427902900623061 1.9120392654533863e-06 0.00010613595700546137 -4 100 1 5 4.8471550029477779 4.5912721624060842 12.975866302829616 1.361702473615606 1.5163577298128434e-06 0.0051043434776858049 -4.3459283627659282 1.5163598208346359e-06 8.4172068877859342e-05 -4 100 2 1 4.3019124900263037 4.1326608527224549 10.289337309154309 0.76349018989235828 1.5466510543683298e-06 0.0026031582345002633 -3.8958818915634272 1.5466535886529029e-06 8.5853654657391224e-05 -4 100 2 3 4.2082402658540339 4.1924642128617453 7.9259940832074829 0.077822593434828446 1.4603391025128065e-07 0.0002457887155045137 -4.3808058412549089 1.4603409191844789e-07 8.1062498983318285e-06 -4 100 2 5 4.3192648651884973 4.3192647263053008 7.6943145242868169 6.2757494556642257e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.696032723178809 3.1036885691353279e-12 1.7228357308550252e-10 -4 100 4 1 4.0051745686255105 4.0050287756412137 7.6955435231948179 0.00041923477874528103 1.5621620535007706e-09 1.3146323476484488e-06 -4.0098149350111498 1.5626505833126274e-09 8.6741636597980988e-08 -4 100 4 3 4.1729334888883667 4.1729333291926638 7.6943138716118415 4.0525182920525538e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313706135203 4.0159515435019528e-12 2.2292265020826827e-10 -4 100 4 5 4.3192648651884973 4.3192647263053008 7.6943136030941908 3.1378565412687465e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330369681005 3.1036885691353279e-12 1.7228357308550252e-10 -4 500 0.5 1 5.8702825782132528 4.4693976428357729 15.293555103261836 9.1684903725434612 5.5837864939537767e-06 0.037592137542268284 2.2238993753736978 5.5837871561608746e-06 0.00030995210414437271 -4 500 0.5 3 5.8702825782601371 4.7098874141239913 12.614251312245898 7.2392855674798611 3.9775195081876335e-06 0.026778147873445998 0.29469457027493995 3.9775201703947493e-06 0.00022078935167331389 -4 500 0.5 5 5.8702825785273234 4.8735460119823859 11.070049105475295 5.9096762924589576 3.0736699021056409e-06 0.020693094523689365 -1.0349147049463188 3.0736705643127693e-06 0.00017061729471622367 -4 500 1 1 5.8702825782132528 4.4693976428357729 10.583226987147309 5.4582397687504702 5.5837864939537767e-06 0.018796068771134142 -1.4863512284192932 5.5837871561608746e-06 0.00030995210414437271 -4 500 1 3 5.8702825782601371 4.7098874141239913 9.1764004492751692 4.0740321162941466 3.9775195081876335e-06 0.013389073936722999 -2.8705588809107745 3.9775201703947493e-06 0.00022078935167331389 -4 500 1 5 5.8702825785273234 4.8735460119823859 8.3690938744740606 3.2307074547159602 3.0736699021056409e-06 0.010346547261844682 -3.7138835426893162 3.0736705643127693e-06 0.00017061729471622367 -4 500 2 1 4.6954196518193392 4.2666338482001569 7.0043222484056828 1.7324278225543366 3.1600890129456843e-06 0.0053187250689607207 -3.7075836555545849 3.1600896371155281e-06 0.0001754143567646699 -4 500 2 3 4.3818724059597676 4.2831122886640625 5.9062436434897769 0.46596584142013375 8.2258435895327966e-07 0.0013844863335737284 -4.3608396169888497 8.2258679147114653e-07 4.5661215180191315e-05 -4 500 2 5 4.3192648651884973 4.3192647263053008 5.5130819206044173 6.6995179914819403e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326808019559 3.1036885691353279e-12 1.7228357308550252e-10 -4 500 4 1 4.0051745686255105 4.0050287756412137 5.5134563870320381 0.00044755306804655781 1.5621620535007706e-09 1.3146323476484488e-06 -4.0097866167218488 1.5626505833126274e-09 8.6741636597980988e-08 -4 500 4 3 4.1729334888883667 4.1729333291926638 5.5130817217279944 4.3261384385928636e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313432515055 4.0159515435019528e-12 2.2292265020826827e-10 -4 500 4 5 4.3192648651884973 4.3192647263053008 5.5130816399126639 3.349759081228143e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330157778465 3.1036885691353279e-12 1.7228357308550252e-10 -4 900 0.5 1 5.8702825782132528 4.4693976428357729 14.486823345796418 9.4678661986674211 5.5837864939537767e-06 0.037592137542268284 2.5232752014976576 5.5837871561608746e-06 0.00030995210414437271 -4 900 0.5 3 5.8702825782601371 4.7098874141239913 12.218462568804931 7.3439103404167465 3.9775195081876335e-06 0.026778147873445998 0.39931934321182538 3.9775201703947493e-06 0.00022078935167331389 -4 900 0.5 5 5.8702825785273234 4.8735460119823859 10.834645644512275 5.9577634211330359 3.0736699021056409e-06 0.020693094523689365 -0.98682757627224049 3.0736705643127693e-06 0.00017061729471622367 -4 900 1 1 5.8702825782132528 4.4693976428357729 10.386574091776176 5.4947284290212259 5.5837864939537767e-06 0.018796068771134142 -1.4498625681485375 5.5837871561608746e-06 0.00030995210414437271 -4 900 1 3 5.8702825782601371 4.7098874141239913 9.0647650148848662 4.0887872504008556 3.9775195081876335e-06 0.013389073936722999 -2.8558037468040656 3.9775201703947493e-06 0.00022078935167331389 -4 900 1 5 5.8702825785273234 4.8735460119823859 8.291443091616145 3.2386385257402321 3.0736699021056409e-06 0.010346547261844682 -3.7059524716650443 3.0736705643127693e-06 0.00017061729471622367 -4 900 2 1 4.7001590005524445 4.2680103979609116 6.9739042600974877 1.7430952307144043 3.1766187767125022e-06 0.0053465462058244007 -3.7055833611199773 3.1766199448097514e-06 0.00017633194253731621 -4 900 2 3 4.3835181336482059 4.2839279197297548 5.8915646430398301 0.46961108249062655 8.2866264017170841e-07 0.0013947166487832722 -4.3605988835199989 8.2866496927857779e-07 4.5998610562230239e-05 -4 900 2 5 4.3192648651884973 4.3192647263053008 5.5010162870367925 6.7018617921910106e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326805675754 3.1036885691353279e-12 1.7228357308550252e-10 -4 900 4 1 4.0051745686255105 4.0050287756412137 5.5013859410781105 0.0004477097136326158 1.5621620535007706e-09 1.3146323476484488e-06 -4.0097864600762634 1.5626505833126274e-09 8.6741636597980988e-08 -4 900 4 3 4.1729334888883667 4.1729333291926638 5.5010160907160035 4.3276518746360182e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313431001625 4.0159515435019528e-12 2.2292265020826827e-10 -4 900 4 5 4.3192648651884973 4.3192647263053008 5.5010160099520302 3.3509309349533112e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330156606611 3.1036885691353279e-12 1.7228357308550252e-10 -4 1500 0.5 1 5.8702825782132528 4.4693976428357729 14.385044944532346 9.5056358688529059 5.5837864939537767e-06 0.037592137542268284 2.5610448716831424 5.5837871561608746e-06 0.00030995210414437271 -4 1500 0.5 3 5.8702825782601371 4.7098874141239913 12.162463604700029 7.3587133862367029 3.9775195081876335e-06 0.026778147873445998 0.41412238903178178 3.9775201703947493e-06 0.00022078935167331389 -4 1500 0.5 5 5.8702825785273234 4.8735460119823859 10.797334794126009 5.9653851080829785 3.0736699021056409e-06 0.020693094523689365 -0.97920588932229791 3.0736705643127693e-06 0.00017061729471622367 -4 1500 1 1 5.8702825782132528 4.4693976428357729 10.354161202906722 5.5007425943546071 5.5837864939537767e-06 0.018796068771134142 -1.4438484028151564 5.5837871561608746e-06 0.00030995210414437271 -4 1500 1 3 5.8702825782601371 4.7098874141239913 9.0441361360843437 4.0915138208214525 3.9775195081876335e-06 0.013389073936722999 -2.8530771763834686 3.9775201703947493e-06 0.00022078935167331389 -4 1500 1 5 5.8702825785273234 4.8735460119823859 8.2761538990492678 3.2402001284409052 3.0736699021056409e-06 0.010346547261844682 -3.7043908689643712 3.0736705643127693e-06 0.00017061729471622367 -4 1500 2 1 4.701141534177224 4.2682950946359952 6.9671648654462732 1.7453271594699959 3.1800373192350715e-06 0.0053522999322984377 -3.7051458239431421 3.1800386027255236e-06 0.00017652170983766438 -4 1500 2 3 4.3838977053640029 4.2841159201584436 5.8881099031062636 0.47045269069827733 8.3006364395282359e-07 0.001397074669048461 -4.3605422458378733 8.300659463918794e-07 4.6076377818033828e-05 -4 1500 2 5 4.3192648651884973 4.3192647263053008 5.4981252052449037 6.7024234362556001e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326805114114 3.1036885691353279e-12 1.7228357308550252e-10 -4 1500 4 1 4.0051745686255105 4.0050287756412137 5.4984937713646289 0.00044774724709606417 1.5621620535007706e-09 1.3146323476484488e-06 -4.009786422542799 1.5626505833126274e-09 8.6741636597980988e-08 -4 1500 4 3 4.1729334888883667 4.1729333291926638 5.4981250095018712 4.3280145556323646e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313430638938 4.0159515435019528e-12 2.2292265020826827e-10 -4 1500 4 5 4.3192648651884973 4.3192647263053008 5.4981249289755798 3.351211759206052e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330156325787 3.1036885691353279e-12 1.7228357308550252e-10 -6 100 0.5 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 0.5 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 0.5 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 1 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 1 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 1 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 2 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 2 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 2 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 4 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 4 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 100 4 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 0.5 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 0.5 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 0.5 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 1 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 1 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 1 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 2 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 2 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 2 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 4 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 4 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 500 4 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 0.5 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 0.5 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 0.5 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 1 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 1 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 1 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 2 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 2 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 2 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 4 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 4 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 900 4 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 0.5 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 0.5 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 0.5 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 1 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 1 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 1 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 2 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 2 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 2 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 4 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 4 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -6 1500 4 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +psi_soil ppfd vpd leaf_temp layers psi_stem opt_root_psi ci assim transpiration gc profit e_up uptake +0.5 100 0.5 15 1 1.4270758056424506 1.1539087272869564 31.257235861844791 4.7310032695803681 8.1422740244378988e-06 0.054816831797731273 4.6055059093498105 8.1422742472583521e-06 0.00045197192602044697 +0.5 100 0.5 15 3 1.6382590972862736 1.4348249852562254 28.230295773392683 4.5999669446863871 5.8807184865500825e-06 0.039591194690758266 4.3862388828625214 5.8807187044817758e-06 0.00032643456588852491 +0.5 100 0.5 15 5 1.8092061574112095 1.6399016990422024 25.818220790146675 4.4771996809175327 4.7502555347515307e-06 0.031980495603952969 4.1655864859055161 4.7502558929346261e-06 0.00026368336902218294 +0.5 100 1 15 1 1.6534087564262019 1.3076224186926617 26.509112703600671 4.5142766091578528 1.0069754354505595e-05 0.033896674874775656 4.2928910330016432 1.0069754353983692e-05 0.00055896499328246974 +0.5 100 1 15 3 1.894716996096661 1.6298036623668128 22.560885129586104 4.2774753295022139 7.3813245108427352e-06 0.024846917638790118 3.9068912074685311 7.3813251705680309e-06 0.00040973217710619099 +0.5 100 1 15 5 2.0802207176156107 1.8560597481402348 19.648799508188237 4.0544780925562778 5.9953721925450506e-06 0.020181543144897136 3.5309548684250642 5.9953725110573256e-06 0.00033279891818247713 +0.5 100 2 15 1 1.9325892590091942 1.4918873285332435 20.102575443843747 4.0926107633957276 1.2379548196607508e-05 0.020835936287227474 3.693642109478096 1.2379548221031022e-05 0.00068718002892206615 +0.5 100 2 15 3 2.1729776852103218 1.8351380028407198 15.57207868379745 3.636967641387896 8.9609518604227513e-06 0.015082119239848101 3.0234255918463013 8.960952741945347e-06 0.0004974161943905272 +0.5 100 2 15 5 2.3153969033468762 2.0385032803865486 12.585603664938979 3.2092841759936492 7.0458064228993806e-06 0.011858750528545165 2.4391838476658156 7.0458073543760129e-06 0.00039110781872750557 +0.5 100 4 15 1 2.1746421995595382 1.6456180690633588 12.757020672873406 3.2376910729776682 1.4305795818557067e-05 0.012038995506121326 2.6224484984617416 1.4305796682995104e-05 0.00079410472844824336 +0.5 100 4 15 3 2.2474806329827843 1.8887907875940946 8.8734068251374545 2.4238473397869176 9.3735670249438015e-06 0.0078882945570383344 1.7312095678767767 9.3735678741614365e-06 0.00052032017064454266 +0.5 100 4 15 5 2.212991014827272 1.9597232397272135 6.9074399553755033 1.812320523031588 6.5922832322856743e-06 0.0055477143120983797 1.1570586410770058 6.5922833967000929e-06 0.00036593302229809011 +0.5 500 0.5 15 1 2.2812766801752042 1.7112439794506997 25.895493275867921 14.180562817696165 1.5127835526573314e-05 0.10184624258960147 13.450021172560684 1.5127835678725456e-05 0.00083973553587152129 +0.5 500 0.5 15 3 2.6226804776277843 2.148626538732171 22.287437337211422 13.385528122418995 1.1370913070241663e-05 0.076553236514425943 12.200499671956257 1.1370913143347457e-05 0.00063119140401595656 +0.5 500 0.5 15 5 2.8865324870584814 2.4542168815024903 19.794311290504464 12.672949532703804 9.4372459955106754e-06 0.063535067085320168 11.050079291933642 9.4372462296323947e-06 0.00052385491144226446 +0.5 500 1 15 1 2.7317573418003795 1.9715476363885696 19.444846897667738 12.558929857536992 1.8386672598051978e-05 0.061892975850622402 11.201647883823473 1.8386673792684458e-05 0.0010206313512453209 +0.5 500 1 15 3 3.0593360403967864 2.4243233187446016 15.540165173989667 10.96319993961524 1.348823234808719e-05 0.045403910606217693 9.0168382199805688 1.3488233995280084e-05 0.00074872239773966602 +0.5 500 1 15 5 3.2175198979427253 2.6717407773019461 13.069724588938737 9.5638406857587199 1.0687171090925342e-05 0.035975014985157899 7.2996355028912667 1.0687172466261578e-05 0.00059323743914857497 +0.5 500 2 15 1 3.0011353940080516 2.1120305327183742 12.513033594957225 9.1996882650172864 2.0144083793065625e-05 0.033904375168708277 7.3652481430673165 2.0144085464812072e-05 0.0011181840391236233 +0.5 500 2 15 3 2.9940026353280822 2.3851817693762394 9.2954821111915891 6.7277888035007782 1.3187767645166625e-05 0.022196245134434897 4.9068642458020033 1.3187769329472031e-05 0.0007320438151247311 +0.5 500 2 15 5 2.9123807941675226 2.4719028017205904 7.5705037382454243 5.1397000921969447 9.5389109619065087e-06 0.016054878408752089 3.4701743966032068 9.5389119714930881e-06 0.00052949830538401819 +0.5 500 4 15 1 2.707878703300771 1.9585097680922661 7.3674492650304435 4.9402859396444905 1.822352049734454e-05 0.015335943847922856 3.6217954871462714 1.8223521505910895e-05 0.0010115748823708518 +0.5 500 4 15 3 2.5045282167856686 2.068825138898692 5.5882830256336185 3.0753370737872778 1.0757654614741469e-05 0.0090530689243641712 2.0623050119614508 1.0757655622419485e-05 0.0005971499096541485 +0.5 500 4 15 5 2.3515498387293619 2.0660504452236692 4.7417207180594687 2.1102108866857123 7.2043692020612226e-06 0.0060628132505250705 1.2967743142903365 7.2043694187172156e-06 0.00039990948757797479 +0.5 900 0.5 15 1 2.5011542191413296 1.8419429576531936 25.721619161415312 15.908445722653463 1.6764477309455815e-05 0.11286472674478223 14.900098293636528 1.6764478169952914e-05 0.00093058441132128306 +0.5 900 0.5 15 3 2.8553992925999241 2.2995869361644283 22.249799883344686 14.781959851834301 1.2530545937065702e-05 0.084360318371045559 13.214432054402785 1.2530547466595839e-05 0.00069556189101281369 +0.5 900 0.5 15 5 3.106151425262377 2.6007962159643574 19.822917113976946 13.784619918563667 1.0279633855997786e-05 0.069206336993232698 11.7461879700239 1.0279634008179982e-05 0.00057061526551096208 +0.5 900 1 15 1 2.930858516377512 2.0765846467471407 19.306769018992579 13.546905464881743 1.9700761736656422e-05 0.066316445452720335 11.843641502036018 1.9700763363384183e-05 0.0010935755405708679 +0.5 900 1 15 3 3.1767581276860066 2.4926309142076901 15.426922458200531 11.442027545119302 1.4012468901499191e-05 0.04716858880817687 9.2615065437143986 1.4012469162353296e-05 0.00077782232374983603 +0.5 900 1 15 5 3.2800412282439741 2.710498846183695 12.973142132875221 9.7980501253756547 1.090976317312951e-05 0.03672430152925299 7.4033204691431509 1.090976499376541e-05 0.0006055933940474832 +0.5 900 2 15 1 3.0450886417613527 2.1337507430139233 12.386797130368574 9.3665564262021199 2.0415705378407326e-05 0.034361539675565343 7.4478585288409356 2.041570607014201e-05 0.0011332615081955043 +0.5 900 2 15 3 3.0061089449125782 2.3924944271502917 9.2355240800259093 6.7696216180109285 1.3243906110355754e-05 0.022290731416596953 4.9257309267967191 1.3243907606735815e-05 0.00073516001147575991 +0.5 900 2 15 5 2.9174849870396038 2.4753820162221598 7.536207334410113 5.1559227091707402 9.5589097646129507e-06 0.0160885382622778 3.4771092947284128 9.5589110962128811e-06 0.00053060844275397618 +0.5 900 4 15 1 2.7117138516075068 1.9606099441737317 7.3335998046933133 4.9525425723291532 1.8249801891855117e-05 0.015358060869193146 3.6278622558269329 1.8249803093826081e-05 0.0010130337548612867 +0.5 900 4 15 3 2.5057182579900754 2.069638741676223 5.5730504189705474 3.0784867972264052 1.0763907750760056e-05 0.009058331230451978 2.0637993945339472 1.0763908802642431e-05 0.00059749701929738726 +0.5 900 4 15 5 2.3521204816617938 2.0664841010292712 4.7324852546661536 2.1114949209254075 7.2068652136032123e-06 0.0060649137608439901 1.297362582042668 7.2068654546686163e-06 0.00040004804078093903 +0.5 1500 0.5 15 1 2.5931813840435893 1.894634108786782 25.770296836572996 16.477998568401134 1.7424079678424497e-05 0.11730541641017796 15.3373513514981 1.7424080784876701e-05 0.00096719848930761597 +0.5 1500 0.5 15 3 2.9312814836170871 2.3468696653822798 22.290980821875223 15.174985138383267 1.2893623795594221e-05 0.086804694210117411 13.470945153103296 1.2893625416000684e-05 0.00071571609303362109 +0.5 1500 0.5 15 5 3.164443104122554 2.6382280651002139 19.844466696904352 14.057951861478927 1.0494674816796704e-05 0.07065407310999286 11.902481529149078 1.0494674960980749e-05 0.00058255203780076324 +0.5 1500 1 15 1 2.9794304417823492 2.1011766071129339 19.281530084223558 13.775188504193377 2.0008341691397746e-05 0.06735181705731165 11.981736411403519 2.0008342605845412e-05 0.0011106490483400173 +0.5 1500 1 15 3 3.1990865196290206 2.5053144981170208 15.395064332574272 11.53643495831383 1.4109792010341915e-05 0.047496196579141822 9.3102174479390243 1.4109793856289524e-05 0.00078322474916955453 +0.5 1500 1 15 5 3.2918796782386277 2.7177484504841605 12.947295105487171 9.8448459612333821 1.0951395266992813e-05 0.03686444293691396 7.4251234330926348 1.0951396234144393e-05 0.00060790431496777098 +0.5 1500 2 15 1 3.0533887316052439 2.1378131088771966 12.356198128922173 9.4002673387594911 2.0466503441633044e-05 0.034447037562247165 7.4654739411566133 2.0466504767205668e-05 0.0011360813081990378 +0.5 1500 2 15 3 3.0088258474321448 2.3941318307884547 9.2199650151853412 6.7794737636446403 1.3256476150605965e-05 0.022311887968808855 4.9304113893206667 1.3256477501527865e-05 0.00073585775750917932 +0.5 1500 2 15 5 2.9187607434288965 2.4762509370048669 7.5267842537144354 5.1601140783672648 9.5639043639490063e-06 0.016096944639626434 3.4789754417493657 9.5639057618451873e-06 0.00053088569313600815 +0.5 1500 4 15 1 2.7126825105121495 1.9611400221343682 7.3242895634782341 4.9557547253279761 1.8256435208450969e-05 0.015363643114997641 3.6295085552909487 1.8256436451373855e-05 0.0010134019678808689 +0.5 1500 4 15 3 2.5060518758617429 2.0698667932620811 5.5685727091965376 3.0793885487450132 1.0765660492889556e-05 0.0090598062448369234 2.0642368022500959 1.0765661556351781e-05 0.0005975943134250226 +0.5 1500 4 15 5 2.3522879976514237 2.0666113966729673 4.7296867094021682 2.1118771526419264 7.2075978939578894e-06 0.0060655303455911273 1.2975404975974949 7.2075981423254771e-06 0.00040008871175828349 +1 100 0.5 15 1 1.7391373156757322 1.5148805959302236 29.083208337785024 4.6392354746567932 6.3942943248732606e-06 0.043048779176400029 4.3708562950048675 6.3942946253795099e-06 0.00035494280462833804 +1 100 0.5 15 3 1.9663652446680653 1.7912730104765946 25.873640002657417 4.4802347179575639 4.7721240637324448e-06 0.032127722714120552 4.0547442943665803 4.7721247693795351e-06 0.00026489729499747626 +1 100 0.5 15 5 2.1493766096015383 1.9987318750952885 23.419602326966462 4.334550329729657 3.9336012709276583e-06 0.026482473886362382 3.7447948502697153 3.9336016222502949e-06 0.00021835146390509547 +1 100 1 15 1 1.9625941269612672 1.6634580180143912 24.054181941278785 4.3745703400345723 8.255812547066679e-06 0.027790607782780669 3.9520981815617393 8.2558132605759833e-06 0.00045827439692345173 +1 100 1 15 3 2.2142240386119907 1.9758626636900083 20.106654054020098 4.09294729029107 6.191552226196622e-06 0.020841921797990541 3.4363718479133434 6.1915524359509297e-06 0.00034368872805722619 +1 100 1 15 5 2.4034029878288918 2.1971967588181878 17.286379673076585 3.8310262891470988 5.0757473215598434e-06 0.01708591398045824 2.9528751262888613 5.0757475116756947e-06 0.00028175118022068804 +1 100 2 15 1 2.228488461384492 1.8341283174600069 17.617053881018201 3.8650955313467961 1.0393078388542529e-05 0.017492521996172381 3.1932020093233184 1.0393079164705849e-05 0.00057691252648936161 +1 100 2 15 3 2.4510618263991666 2.1463507880767829 13.313480995154798 3.3262718077709166 7.5018266859076992e-06 0.012626275239045493 2.3859798990081789 7.5018277886214506e-06 0.00041642119281828758 +1 100 2 15 5 2.5634858382205641 2.3187873487996264 10.5541551428289 2.8254320973599629 5.7751341188561837e-06 0.0097200903166770134 1.7284986292395095 5.7751346627426384e-06 0.00032057366987191997 +1 100 4 15 1 2.3950199136627663 1.9369559267188385 10.656958979033064 2.847226212578283 1.1680140522739637e-05 0.0098293839117795569 1.979741911040354 1.1680141100512984e-05 0.00064835643078062634 +1 100 4 15 3 2.3929428651528819 2.1051158612162881 7.3050430037279215 1.9515316081728571 7.1849877916382538e-06 0.0060465028882115152 1.0866780094483011 7.1849884664530721e-06 0.00039883366452695378 +1 100 4 15 5 2.311168530955749 2.1258596465263766 5.7042781426882172 1.3291900540974999 4.665286827366998e-06 0.0039260568137413372 0.56406266647418668 4.6652878309307411e-06 0.00025896685156429316 +1 500 0.5 15 1 2.6022141805996126 2.0598056108659679 24.239652930171516 13.843989659857463 1.3217116478726718e-05 0.088982567853997274 12.689853607231102 1.3217117139603216e-05 0.00073367289145729762 +1 500 0.5 15 3 2.9647052441022557 2.4901518382672272 20.759138413492344 12.968427085232411 1.0141542556488343e-05 0.068276654755172472 11.202543232756259 1.0141542571319255e-05 0.00056294990681761057 +1 500 0.5 15 5 3.2422039682132207 2.7938491449058871 18.416306480804607 12.199280178236247 8.5045172911219319e-06 0.057255588852588586 9.8838456491509685 8.5045173669822721e-06 0.00047207978723187743 +1 500 1 15 1 3.0534532263740797 2.3044498911669811 17.844399244674058 11.982319369344291 1.6275284320459045e-05 0.054785648356783644 10.047400678394236 1.6275285650329859e-05 0.00090342967806438293 +1 500 1 15 3 3.355567547728127 2.7213978136079584 14.166864055840524 10.228002137736871 1.1914749188370317e-05 0.040107272256545035 7.6724242014919852 1.1914750638474726e-05 0.00066137944149179714 +1 500 1 15 5 3.4809735729825024 2.941197430212307 11.854251308574554 8.7447420050102007 9.349866703220548e-06 0.031473398516394899 5.9156429118633014 9.3498688732681487e-06 0.0005190046557462198 +1 500 2 15 1 3.2062007927591365 2.3792181203040257 11.168928956580078 8.2436393809298405 1.7209150338001184e-05 0.028964607940875745 6.0027884559215421 1.720915224439736e-05 0.00095526795694684218 +1 500 2 15 3 3.1433548913274634 2.5995162221945929 8.2542388752773483 5.7916600693371514 1.0980409564046137e-05 0.018481055241323374 3.6788277197708479 1.0980411210241696e-05 0.00060951491591683025 +1 500 2 15 5 3.0314700745370935 2.6544613750311488 6.6972978185179599 4.2629452671770967 7.7042701458774267e-06 0.012967006497303452 2.370530820630167 7.7042701454306829e-06 0.00042765862589123969 +1 500 4 15 1 2.7992609213577193 2.17076533098657 6.5056873262118255 4.0637788317123951 1.4604618228348951e-05 0.012290468524067398 2.5936316161967219 1.4604619544089053e-05 0.00081069217563636158 +1 500 4 15 3 2.5666126847989426 2.2270557678987348 4.9601068405159641 2.3642004340303959 8.1218083021170648e-06 0.0068348811132849293 1.2627097622339418 8.1218090257800698e-06 0.00045083591594671497 +1 500 4 15 5 2.3978981911160466 2.1929641681699308 4.230049450982607 1.5010617382583473 5.0513961688353355e-06 0.0042509858624824809 0.62992392653478402 5.0513966079508069e-06 0.0002803994786539443 +1 900 0.5 15 1 2.8248308157533688 2.1847111857099675 24.250315377279428 15.469431438428687 1.4778954718447882e-05 0.099497446599799519 13.955318822846607 1.4778954717710948e-05 0.0008203693987072411 +1 900 0.5 15 3 3.191216647174977 2.6277924976468858 20.867672506384864 14.237608895573688 1.1197226951642876e-05 0.075383916651172181 12.027537851879298 1.1197228380739941e-05 0.0006215502848037714 +1 900 0.5 15 5 3.4474423227596223 2.921231671106995 18.536019949352667 13.174159561625679 9.2353613237811983e-06 0.062175904023561261 10.418884349272156 9.2353613514293667e-06 0.00051264842361528542 +1 900 1 15 1 3.2264507801789923 2.3888012770097968 17.787058110766125 12.790979594713299 1.7328818363227902e-05 0.058332040816820689 10.508286207115271 1.7328819003319852e-05 0.00096191057470551491 +1 900 1 15 3 3.4441124178165867 2.769495752835077 14.087872991456999 10.576620610913803 1.2283300778866756e-05 0.041347885780751763 7.8286513149902888 1.2283300787527436e-05 0.00068183740147251932 +1 900 1 15 5 3.5255415481140506 2.9673514552981457 11.784461992537459 8.9070474944520281 9.4998479947917618e-06 0.031978263570567114 5.9791629562089756 9.4998486741495515e-06 0.00052732992917843753 +1 900 2 15 1 3.2341882136622813 2.3924422719683998 11.080224574116347 8.3483488315326291 1.7374282990180815e-05 0.029242541623520042 6.0495946255209603 1.7374283098410003e-05 0.00096443425469941728 +1 900 2 15 3 3.1511358186388074 2.6041434209007082 8.2129573482224174 5.8179314663000827 1.1015892673603013e-05 0.018540776630041129 3.6894054160808607 1.101589381152013e-05 0.00061148453019817543 +1 900 2 15 5 3.0347663382225534 2.6567037336376291 6.6737927197978983 4.2730846615985794 7.7171479396993813e-06 0.012988681027531286 2.3743229267206418 7.7171479839973968e-06 0.00042837346566735479 +1 900 4 15 1 2.8016722162596914 2.1720850424213833 6.4825950957763236 4.0711743764056418 1.4621116374947054e-05 0.012304352485174702 2.5969092432350735 1.4621117580119191e-05 0.00081160797003159541 +1 900 4 15 3 2.5673708841130631 2.2275794580212356 4.9496612366715009 2.3660764491539128 8.1258306736377827e-06 0.0068382661268330093 1.2634791203832965 8.1258314397414245e-06 0.00045105919732120036 +1 900 4 15 5 2.3982541568618814 2.1932379656102254 4.2237867712950798 1.5017927230491708 5.0529714050799642e-06 0.0042523114973727506 0.63020242398306625 5.0529718270626416e-06 0.00028048691796073502 +1 1500 0.5 15 1 2.9105586467347213 2.2306705747216835 24.339385614815612 15.979829568633408 1.5353400377651809e-05 0.10336482946888594 14.31361355807347 1.5353401256896362e-05 0.00085225652272530458 +1 1500 0.5 15 3 3.2580399229224772 2.6665142772483632 20.923395465831724 14.572509735433876 1.1494087678994574e-05 0.077382494015401024 12.223998570275747 1.1494088994973954e-05 0.00063802880904656977 +1 1500 0.5 15 5 3.4974067674841236 2.9508922340329891 18.56328999906232 13.39976462910983 9.4054648642200367e-06 0.063321104631701958 10.534324577115152 9.4054660358551981e-06 0.00052209081520150971 +1 1500 1 15 1 3.2643363351400967 2.4065194635867031 17.768863411191603 12.964889208119915 1.7550050349641567e-05 0.059076749024326213 10.603182074890173 1.7550052101271061e-05 0.00097419106862453846 +1 1500 1 15 3 3.4607785023811162 2.7783603462896931 14.063347394364417 10.645163715644083 1.23512139227837e-05 0.041576494113987464 7.8605817180238748 1.2351214987919876e-05 0.00068560727104745355 +1 1500 1 15 5 3.5343857166066264 2.9724889349299346 11.765122684399877 8.9407906745055516 9.5293054079935097e-06 0.03207742272805985 5.9932212164473029 9.5293069535330765e-06 0.00052896513758163071 +1 1500 2 15 1 3.239823461039486 2.3950868304150985 11.057835364565207 8.3706910487029358 1.7407304362316228e-05 0.029298119678147178 6.0602146259953038 1.740730436955627e-05 0.00096626724227345372 +1 1500 2 15 3 3.1530013923509541 2.60525110910796 8.2018016676096632 5.8244609074436786 1.1024386750984807e-05 0.018555072955911436 3.6921653815670714 1.1024387740012799e-05 0.00061195602220442957 +1 1500 2 15 5 3.0356352754361327 2.6572945334547073 6.667111569777278 4.2758203900431164 7.7205408441283775e-06 0.012994391602698368 2.3753838915495304 7.7205409185726294e-06 0.00042856180508313237 +1 1500 4 15 1 2.8023138432586112 2.1724360470203954 6.47602003656527 4.0731950709056619 1.462550438456759e-05 0.012308045200265317 2.5978332013702019 1.462550555678395e-05 0.00081185154353505132 +1 1500 4 15 3 2.5675909200632425 2.2277314226562406 4.9465179632589766 2.3666285350348377 8.1269978858496521e-06 0.0068392483904380266 1.2637099262758491 8.1269986641282252e-06 0.00045112398912729537 +1 1500 4 15 5 2.3983614986301434 2.193320526789325 4.2218541830580101 1.5020150298432391 5.053446403253614e-06 0.0042527112305263985 0.63028825493130103 5.0534468200808321e-06 0.0002805132844896382 +2 100 0.5 15 1 2.525142687932648 2.3452619975210345 24.442536959303006 4.3982151146015624 4.2538181212338741e-06 0.028638293399357327 3.3562855837459353 4.2538191360249271e-06 0.00023612651324035123 +2 100 0.5 15 3 2.7672160413894638 2.6115220260059111 21.334848497644259 4.1895690221878521 3.3773732445269163e-06 0.022737738929901809 2.7735852252668796 3.377373678869224e-06 0.00018747564134716758 +2 100 0.5 15 5 2.9630880586088653 2.8190188386199369 19.116260422780233 4.0079069939280254 2.8876901686453258e-06 0.01944100945061486 2.245038898083072 2.8876901672958232e-06 0.00016029365347187472 +2 100 1 15 1 2.7265846282440953 2.4682924163642235 19.150586947977391 4.0109704516983573 5.7893106379097305e-06 0.019487901445629764 2.6621424991178246 5.7893120099905826e-06 0.0003213606444624248 +2 100 1 15 3 2.977848889359179 2.7562288344127097 15.588599240424038 3.6389908974839669 4.4860023073291866e-06 0.015100722057931146 1.8485090848340509 4.4860031004616564e-06 0.00024901488206836836 +2 100 1 15 5 3.1587919078052744 2.9602440790483309 13.142982445426792 3.299703383996071 3.6973310930309707e-06 0.012445907372983086 1.1556914243639436 3.6973316118984789e-06 0.00020523628153752311 +2 100 2 15 1 2.9232267664770362 2.5825294563468235 12.854513183603807 3.2536060843082462 7.2138740677320183e-06 0.012141624078052964 1.564315560321424 7.2138756395075649e-06 0.00040043717121884901 +2 100 2 15 3 3.0605506297892089 2.8110945804056522 9.2041469196786281 2.5102952101004825 4.9060704235877675e-06 0.0082573749173284784 0.56156734209983639 4.9060721149250919e-06 0.00027233261809187301 +2 100 2 15 5 3.0734167016868374 2.8993973185666313 6.9768871813912039 1.8372917016161776 3.3485849795245483e-06 0.0056359813926699217 -0.13657523732736299 3.3485866100120824e-06 0.00018587769136897488 +2 100 4 15 1 2.8273949614561333 2.5276257583835253 6.8659699832141285 1.7972719534627117 6.5293620556539575e-06 0.005494763202470037 0.27871435056325655 6.5293620793477391e-06 0.00036244030415474545 +2 100 4 15 3 2.6524189613564046 2.5299357359865544 4.6486258811614896 0.80817894762280085 2.7518987367911342e-06 0.0023158513476442886 -0.42254852983125557 2.7519000961961459e-06 0.00015275604197591706 +2 100 4 15 5 2.4824438870701759 2.449687103805104 3.6945824454223608 0.2314077099629217 7.6725124843155325e-07 0.00064567776928226245 -0.75119176855868564 7.6725126109849867e-07 4.2589578745406533e-05 +2 500 0.5 15 1 3.4075446695161782 2.8349533535174736 21.041275656123162 13.049857141754579 1.0357092944514989e-05 0.069727820526421236 10.381796328822858 1.0357095026694429e-05 0.00057491507225614373 +2 500 0.5 15 3 3.8167263355846548 3.2499539728449225 18.036837097899902 12.056764090451692 8.2599441117891881e-06 0.055609030803389928 8.4721934125114942 8.2599463293360096e-06 0.00045850382066811042 +2 500 0.5 15 5 4.1333329692832042 3.5474349378045025 16.069809603382748 11.219883745318331 7.0547792886099722e-06 0.047495410799632022 6.9248402613338973 7.0547792957860616e-06 0.00039160584489514636 +2 500 1 15 1 3.824223205086315 3.0145323734764879 14.760327623176723 10.558439189455928 1.2588884054298436e-05 0.042376536189670813 6.9568616233759979 1.2588886488004642e-05 0.00069880024912598619 +2 500 1 15 3 4.0459447946540861 3.3571380448258372 11.604126740317742 8.5651498476849337 9.0771802636351885e-06 0.03055548500430914 4.463742386087926 9.0771819167318646e-06 0.0005038679942676583 +2 500 1 15 5 4.110401336582461 3.5362706447429346 9.6681775245732844 7.0464855495891205 6.9910962939892361e-06 0.023533336539591998 2.8019892764784009 6.9910983865649597e-06 0.00038807096234054733 +2 500 2 15 1 3.6545904945051935 2.9458679988783034 8.6115273537722103 6.1205277392456559 1.1735994750526898e-05 0.019752775707616348 2.9032755151767828 1.1735994793927943e-05 0.00065145683008203958 +2 500 2 15 3 3.4842026238783079 3.0720836915941003 6.3148153064897041 3.862908979826571 6.9020287158206185e-06 0.011616759213786384 1.026677091690217 6.9020308149831811e-06 0.00038312688398463399 +2 500 2 15 5 3.3064878295435691 3.0624776162175102 5.0658848899920734 2.4859558169679041 4.2829684800382041e-06 0.007208636127345484 0.035277232782320311 4.2829684853976187e-06 0.00023774457315557142 +2 500 4 15 1 3.0026720112487855 2.6268796215017147 4.8755334231116914 2.2662590861494811 7.7666017463108896e-06 0.0065359582023659683 0.42890144656987861 7.7666033776222323e-06 0.00043111869984025712 +2 500 4 15 3 2.7055400303625561 2.5679107956794462 3.7541319560016442 0.9163025659328915 3.0430676901818512e-06 0.0025608836244817514 -0.39842093188341055 3.0430685614353892e-06 0.0001689185990250008 +2 500 4 15 5 2.5001554684080762 2.4637610623687634 3.2359914026099621 0.25903085275413218 8.481249736982093e-07 0.00071373678727730398 -0.74793229293176944 8.4812578544605943e-07 4.707886680244571e-05 +2 900 0.5 15 1 3.6333885859624502 2.9368521841362059 21.327108253283917 14.425290500774357 1.1623962940075393e-05 0.078256862812126113 11.255848154387289 1.162396435089127e-05 0.00064523809885602386 +2 900 0.5 15 3 4.0308562427518879 3.3504839851280881 18.265758652377009 13.038305282683179 9.026468863432208e-06 0.060769561909749227 8.9705855811591597 9.0264714049048403e-06 0.0005010530893646872 +2 900 0.5 15 5 4.3179908366497166 3.632167908615239 16.213634584616408 11.916140661019549 7.5378720778801313e-06 0.050747772006419993 7.2227930700060163 7.5378741319444999e-06 0.00041842210002467387 +2 900 1 15 1 3.9357527330052142 3.056291156482005 14.735072271458936 11.004228102969993 1.3107285155213868e-05 0.044121571168065685 7.1501716072381623 1.3107285587935153e-05 0.00072757621914710819 +2 900 1 15 3 4.0927527027585517 3.3774168881653552 11.55358394150041 8.7264623326305131 9.2317042870088719e-06 0.031075641742620869 4.521002801677831 9.2317066535861107e-06 0.0005124455539043081 +2 900 1 15 5 4.1338229965314879 3.5476719741394849 9.6293029499284106 7.1211508830585393 7.0561312740221734e-06 0.023752256435356649 2.8250294963752474 7.0561312741898521e-06 0.00039168089226699151 +2 900 2 15 1 3.665054385462688 2.9502823558273943 8.5704715798881175 6.1571750829788616 1.1790843038605897e-05 0.019845090501155477 2.9162975814714129 1.1790843927069033e-05 0.00065450146694804516 +2 900 2 15 3 3.4872861688076675 3.0738486023394187 6.2966056814819602 3.8725479649231875 6.9155127068975807e-06 0.011639454030633909 1.0295009845399448 6.9155146713765498e-06 0.00038387536338476547 +2 900 2 15 5 3.3077514015313452 3.0633347759331206 5.0559991900680537 2.4895090963074775 4.2878769149947182e-06 0.0072168974819926558 0.036146967243160688 4.2878769133959554e-06 0.00023801703654709717 +2 900 4 15 1 3.0034992218289829 2.6273356838813786 4.8661043742768424 2.2685261311224387 7.7722845968109135e-06 0.0065407405865478396 0.42959704209995642 7.7722862011103806e-06 0.00043143414938164753 +2 900 4 15 3 2.7057690948054285 2.5680737353133938 3.7502108427057248 0.9167778720479699 3.0443168585655522e-06 0.0025619348580341174 -0.39831432982119319 3.044317743753102e-06 0.00016898794025829042 +2 900 4 15 5 2.5002334749370285 2.4638229807833447 3.2339752866254896 0.25915372843944806 8.4848076602247031e-07 0.00071403620313974291 -0.7479174954186123 8.4848158164864555e-07 4.7098616799813795e-05 +2 1500 0.5 15 1 3.705258224812205 2.9670251600066964 21.435182102180214 14.804345177847452 1.1998853123071474e-05 0.080780763634210717 11.472545274976728 1.1998854264812507e-05 0.00066604797473286193 +2 1500 0.5 15 3 4.083683328319907 3.3735306944554537 18.311346783499751 13.264108091676784 9.2020946466088208e-06 0.061951940319864431 9.0787523067866083 9.2020962208696282e-06 0.00051080189957644346 +2 1500 0.5 15 5 4.3577195071163741 3.649187205603031 16.229624775536518 12.061346366224997 7.6348582847019432e-06 0.051400719398032528 7.2847039977162567 7.6348597158625362e-06 0.00042380570168540306 +2 1500 1 15 1 3.9573686641488242 3.0640729167681053 14.718968355224144 11.092374875297409 1.3203861801434383e-05 0.044446666206354103 7.1895812630719131 1.3203864227276875e-05 0.00073293723160015964 +2 1500 1 15 3 4.1022456020180522 3.3814623689925423 11.53820545248713 8.7603315614280994 9.2625270275068617e-06 0.031179396846929098 4.5338607208272377 9.2625295662028201e-06 0.00051415651214004 +2 1500 1 15 5 4.139014414091716 3.5501792288199265 9.6180886556183118 7.1382176731964959 7.0704314990657739e-06 0.023800393665111632 2.830682751358915 7.0704316576894154e-06 0.00039247469651342855 +2 1500 2 15 1 3.6675192133967012 2.9513187830472969 8.5593071616572338 6.1660890854605075 1.1803720214748902e-05 0.019866763991771924 2.9196439139851522 1.1803721363765144e-05 0.00065521628441660531 +2 1500 2 15 3 3.4881178855929833 3.0743242911345741 6.2913226440665273 3.8751904214605446 6.9191469663212473e-06 0.011645570828807815 1.0303046071180932 6.9191488840989447e-06 0.00038407709598106828 +2 1500 2 15 5 3.3081164227664295 3.0635823357475953 5.0530183639424493 2.4905445860881965 4.2892945308694539e-06 0.0072192834619635446 0.036407059774692829 4.2892945311054077e-06 0.00023809572751070819 +2 1500 4 15 1 3.0037404878733098 2.6274686774930611 4.8632525420259372 2.2691939974501745 7.773941785374284e-06 0.0065421351881429033 0.42980646333212769 7.7739433811225097e-06 0.00043152613828046125 +2 1500 4 15 3 2.7058398922139593 2.5681240939587924 3.7489805014375754 0.91692525504798972 3.0447029303327146e-06 0.002562259755462325 -0.3982809141462077 3.0447038198083056e-06 0.00016900937106901503 +2 1500 4 15 5 2.5002582342138409 2.463842633567924 3.2333321211941382 0.25919275437049105 8.4859369379675456e-07 0.00071413123713745736 -0.7479127749239618 8.4859451065152811e-07 4.7104885409465894e-05 +3 100 0.5 15 1 3.4675059500349152 3.2655675612116877 20.701416604354947 4.1408840402186362 3.2285600321368866e-06 0.021735872767158972 1.3414904173667415 3.2285617051243442e-06 0.00017921519317925863 +3 100 0.5 15 3 3.7213245705181697 3.5259960756746507 18.137754813634984 3.916781288102869 2.695726258140796e-06 0.018148636661173154 0.54859246226082226 2.6957262563139272e-06 0.00014963787156891076 +3 100 0.5 15 5 3.9328379175845596 3.7353891501423706 16.410029751640007 3.7356800630296485 2.3827776054080902e-06 0.016041749370633993 -0.1117979952546504 2.3827777957409585e-06 0.00013226632227260386 +3 100 1 15 1 3.6532452896296452 3.3579740538416134 15.239883014080174 3.5955880715795949 4.3700706945340633e-06 0.0147104745853236 0.3813716938222238 4.3700707019132974e-06 0.00024257955603182335 +3 100 1 15 3 3.897273076672755 3.6250436309311569 12.343209736836197 3.1681651097997836 3.4472855154723874e-06 0.011604207233338026 -0.59893981072275126 3.4472879120503534e-06 0.0001913565313377937 +3 100 1 15 5 4.0698281505124267 3.8162029569007916 10.408789433937148 2.794123806386501 2.8415423765373232e-06 0.0095651626335141182 -1.3604653066527956 2.841542515828344e-06 0.00015773202974345512 +3 100 2 15 1 3.7182980230585718 3.388533929695174 8.9640562335593774 2.4479434866537519 4.7472013307939329e-06 0.0079899833903607099 -0.91338852785138203 4.7472013805505235e-06 0.0002635138151845975 +3 100 2 15 3 3.7144363678821359 3.5219643114996724 6.1036308864486184 1.5009533373240185 2.6651105601870116e-06 0.004485630085085914 -1.8516311369831313 2.6651108296439376e-06 0.00014793843073238622 +3 100 2 15 5 3.5950521250353913 3.5160748032929483 4.4043676682664197 0.67136268429137502 1.1351720929852943e-06 0.0019106006963131299 -2.4118672999064477 1.1351728497907589e-06 6.3012647781890587e-05 +3 100 4 15 1 3.21236351564652 3.1268512086383211 4.0364805831426525 0.45171383487374761 1.5119325670575711e-06 0.0012723618882322697 -1.8018415131550225 1.5119342683199617e-06 8.392640956536007e-05 +3 100 4 15 3 3.1718079687688916 3.1718075251234743 3.361472054878722 2.3849817223364767e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704360025386209 7.8605668043621887e-12 4.3633454367816762e-10 +3 100 4 15 5 3.3170442487608387 3.3170439012574113 3.3614711552711181 1.7359976419717427e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731248171258904 6.1738007589111003e-12 3.4270334492984183e-10 +3 500 0.5 15 1 4.5233153883223345 3.6857390035850806 18.261414529211986 12.141781869867932 8.404122487948054e-06 0.056579693516416972 7.029115987125075 8.4041246620918214e-06 0.00046650705867842471 +3 500 0.5 15 3 5.0613513411139843 4.0744568571108513 15.708138102536267 11.046160092976326 6.842136877292937e-06 0.046063822614409458 4.9971447150038584 6.8421392545679343e-06 0.00037980234552139518 +3 500 0.5 15 5 5.5113326370152791 4.3455981531473551 13.943894147527715 10.098690503973073 5.831721570913922e-06 0.03926132914275856 3.4770634727564156 5.8317215753768378e-06 0.00032371476965733213 +3 500 1 15 1 4.8243773632812736 3.7595552343116583 11.816887665077143 8.7181548951546155 9.3090819402778307e-06 0.031336109382951886 3.0493716779096705 9.3090819414374222e-06 0.00051674060180057857 +3 500 1 15 3 4.9611330431564342 4.0495630596983805 9.3527297974547139 6.7772994300846072 6.6548167394079218e-06 0.022401356718894889 0.88256000009754754 6.6548167350140155e-06 0.00036940420399744745 +3 500 1 15 5 4.9942011377429347 4.2214588144844711 7.9158039199645067 5.4726917467549798 5.1331156484331879e-06 0.017279026489033539 -0.47402356283799296 5.1331180956487393e-06 0.00028493578105183123 +3 500 2 15 1 4.189977698575893 3.5809006140901309 6.4170902149025277 3.9708491012453919 7.1164971580711732e-06 0.011977729640766753 -0.44812748861500395 7.1164981435834093e-06 0.00039503181479785788 +3 500 2 15 3 3.9246207412129417 3.6397404342376691 4.7210334080960914 2.0859667552108112 3.5587112162921687e-06 0.0059896434821123156 -1.7429583339245238 3.558711285133102e-06 0.00019754156453694711 +3 500 2 15 5 3.67278686331694 3.5689024416460375 3.7136772057821497 0.86576866414733311 1.4360187905067759e-06 0.0024169537975917521 -2.3925784992230739 1.4360204651361094e-06 7.9712487656736578e-05 +3 500 4 15 1 3.2492554414548276 3.1477078667798191 3.4533854087052238 0.53746816193279268 1.7702589744096627e-06 0.0014897556282708422 -1.7926748163683088 1.7702595223886227e-06 9.8265863024625188e-05 +3 500 4 15 3 3.1718079687688916 3.1718075251234743 3.0364502642382956 2.4061391576957192e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704359813811855 7.8605668043621887e-12 4.3633454367816762e-10 +3 500 4 15 5 3.3170442487608387 3.3170439012574113 3.0364497630968215 1.7513978942673702e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731248017256382 6.1738007589111003e-12 3.4270334492984183e-10 +3 900 0.5 15 1 4.7830454904970701 3.7505218159742624 18.488526819932964 13.15048165325415 9.1984093884098357e-06 0.06192712978435326 7.5534024823654349 9.1984118144250468e-06 0.00051059738076186768 +3 900 0.5 15 3 5.2957485726770193 4.1239449641980546 15.738106189792939 11.632548875510979 7.2142537957635027e-06 0.048569052783238031 5.2608639363111429 7.2142543259646976e-06 0.00040045819183817362 +3 900 0.5 15 5 5.6993736816803677 4.3760742730709916 13.866332410999906 10.426168184419446 6.0029619665760911e-06 0.040414183485147026 3.621557660825558 6.0029631706554214e-06 0.00033322027036666228 +3 900 1 15 1 4.8857520459338986 3.7723555504097028 11.755283102677973 8.8843622226021157 9.4658638720812843e-06 0.031863866662969649 3.1120013171105549 9.4658641620661462e-06 0.00052544347277636114 +3 900 1 15 3 4.986498464540281 4.0560864256889495 9.3100758793779743 6.8367992375735307 6.7039109422180275e-06 0.02256661697970213 0.9020970421147938 6.703913087266247e-06 0.00037212950803587272 +3 900 1 15 5 5.0083783866987979 4.2257605423855811 7.887962647203473 5.5033037632648867 5.1573528870845795e-06 0.01736061356350482 -0.46537303493798721 5.1573546784875336e-06 0.00028628113674646316 +3 900 2 15 1 4.1938384286832209 3.5822607532676103 6.3991285376168143 3.9823087821755996 7.1332198566381756e-06 0.01200587550492584 -0.44506323590998509 7.1332204236287253e-06 0.00039596005682091174 +3 900 2 15 3 3.9258025124022118 3.6403712002137163 4.713609895514657 2.0892090636489646 3.5634928336890372e-06 0.0059976913909575149 -1.7423849401611493 3.563492859557226e-06 0.00019780698637564397 +3 900 2 15 5 3.6731764568983092 3.5691638373349366 3.7103462447068285 0.86674538002293111 1.4375068748390625e-06 0.0024194583825608578 -2.3924822186815056 1.4375085846159594e-06 7.979509212411654e-05 +3 900 4 15 1 3.2494246140397451 3.1478029063998392 3.4507355301478118 0.53786449057585373 1.7714359216639437e-06 0.001490746084368842 -1.7926317557562421 1.7714364839793164e-06 9.833119533607085e-05 +3 900 4 15 3 3.1718079687688916 3.1718075251234743 3.035037789744063 2.4062309841310636e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.170435981289359 7.8605668043621887e-12 4.3633454367816762e-10 +3 900 4 15 5 3.3170442487608387 3.3170439012574113 3.0350372902455511 1.7514647028260555e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731248016588294 6.1738007589111003e-12 3.4270334492984183e-10 +3 1500 0.5 15 1 4.8503119343661529 3.7650527929845907 18.527558927972681 13.380652066959453 9.3764207374680093e-06 0.063125568715556246 7.6676748149780209 9.3764230501145096e-06 0.00052047865945681435 +3 1500 0.5 15 3 5.3448749431036049 4.1328739144378144 15.7250937538633 11.747037292704889 7.2813517981537137e-06 0.049020781612303312 5.3144993825427589 7.281353890599832e-06 0.00040418284155425104 +3 1500 0.5 15 5 5.7354799405310777 4.3811764890211728 13.83774169177347 10.487404192469432 6.0316204547505422e-06 0.040607123138261265 3.6512042723756286 6.0316214210793099e-06 0.00033481106972408048 +3 1500 1 15 1 4.8979802953717009 3.7748198281710126 11.736915464891027 8.9184825891060555 9.4960421846167416e-06 0.031965452502332854 3.1259044785997609 9.4960424078746162e-06 0.00052711864601024793 +3 1500 1 15 3 4.9922797722033589 4.0575518897007701 9.2982791566781184 6.8506784088249075 6.7149392244076726e-06 0.022603740238388417 0.90695432255944208 6.7149416405486878e-06 0.00037274169528441229 +3 1500 1 15 5 5.0118606372352863 4.2268087877760943 7.8800238523951078 5.5109680409989377 5.1632588999151931e-06 0.017380494306339027 -0.46307333149057861 5.163260349313798e-06 0.00028660895638711061 +3 1500 2 15 1 4.1948741098562703 3.5826250346287258 6.393905852580577 3.9854285046222042 7.1376985543124085e-06 0.012013413571574804 -0.44419450284494477 7.1376990195124433e-06 0.00039620866053357998 +3 1500 2 15 3 3.9261503862909959 3.6405568082676982 4.7113395521190267 2.0901684456138403 3.5648998514927512e-06 0.0060000595333846518 -1.7422111546226433 3.5648998682008568e-06 0.00019788508843746083 +3 1500 2 15 5 3.6732972276007945 3.5692448608372125 3.7092972122047678 0.86704855599874764 1.437968127954547e-06 0.0024202347146510027 -2.3924519748113302 1.4379698484874761e-06 7.9820696557728345e-05 +3 1500 4 15 1 3.2494777219426689 3.1478327407973268 3.4498954765414069 0.53798903580896151 1.7718053831514009e-06 0.0014910570034706941 -1.7926181148371687 1.7718059499836263e-06 9.8351704134533796e-05 +3 1500 4 15 3 3.1718079687688916 3.1718075251234743 3.034584392545618 2.4062604880858984e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.170435981259855 7.8605668043621887e-12 4.3633454367816762e-10 +3 1500 4 15 5 3.3170442487608387 3.3170439012574113 3.0345838935670546 1.7514861749834409e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731248016373577 6.1738007589111003e-12 3.4270334492984183e-10 +4 100 0.5 15 1 4.5760023535758432 4.2301288559861678 18.272027683013093 3.9297366422365503 2.7213567313139148e-06 0.018321190585618617 -1.2856693341753944 2.7213591949513712e-06 0.000151060737993415 +4 100 0.5 15 3 4.8831975005619492 4.4933288951145611 16.412886593520792 3.7360034795531742 2.3832725184429959e-06 0.016045081310152056 -2.0321162279041234 2.3832730335537004e-06 0.00013229381257583682 +4 100 0.5 15 5 5.1641725268402734 4.710669130176659 15.192803149832063 3.5896142689422321 2.1772651353473472e-06 0.014658162614668267 -2.607545283309749 2.1772652306823216e-06 0.00012085846409560486 +4 100 1 15 1 4.7930752748449068 4.2939090471049015 12.471948108458609 3.1901447672897252 3.4874351236338232e-06 0.011739358317096977 -2.424476951935989 3.4874375904732738e-06 0.00019358521179424224 +4 100 1 15 3 5.0697970275832525 4.5525184191876846 10.342317645808219 2.7796117689908018 2.8204483845172778e-06 0.0094941563145769861 -3.2819606250814255 2.8204506613800378e-06 0.00015656123571357411 +4 100 1 15 5 5.2803700652454033 4.7465774385492079 8.9695169807914432 2.4493851795313168 2.3754165272475535e-06 0.0079960959206767362 -3.9027708106463241 2.3754184428479079e-06 0.0001318578097611939 +4 100 2 15 1 4.5911182715747261 4.2349453593757262 6.2446461252542598 1.5587418677029778 2.7792828976912555e-06 0.0046777927966987791 -3.6857396544290286 2.779285149670347e-06 0.00015427616706468759 +4 100 2 15 3 4.4589289917399908 4.320414881420076 4.3697787212913957 0.65142647773741447 1.1003937293970125e-06 0.0018520654609078464 -4.3328545493522128 1.1003954786648656e-06 6.1082180331105499e-05 +4 100 2 15 5 4.3192648651884973 4.3192647263053008 3.3614697354810676 7.117495334219015e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326390042217 3.1036885691353279e-12 1.7228357308550252e-10 +4 100 4 15 1 4.0051745686255105 4.0050287756412137 3.3621278877520977 0.00047547217990651092 1.5621620535007706e-09 1.3146323476484488e-06 -4.009758697609989 1.5626505833126274e-09 8.6741636597980988e-08 +4 100 4 15 3 4.1729334888883667 4.1729333291926638 3.3614693859629696 4.5960427863533937e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313162610707 4.0159515435019528e-12 2.2292265020826827e-10 +4 100 4 15 5 4.3192648651884973 4.3192647263053008 3.3614692421754837 3.5587478774967707e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960329948789674 3.1036885691353279e-12 1.7228357308550252e-10 +4 500 0.5 15 1 5.8702825782132528 4.4693976428357729 13.501402200605515 9.8335531406918584 5.5837864939537767e-06 0.037592137542268284 2.8889621435220949 5.5837871561608746e-06 0.00030995210414437271 +4 500 0.5 15 3 5.8702825782601371 4.7098874141239913 10.567452426355407 7.7803466063108395 3.9775195081876335e-06 0.026778147873445998 0.8357556091059184 3.9775201703947493e-06 0.00022078935167331389 +4 500 0.5 15 5 5.8702825785273234 4.8735460119823859 8.875148747928101 6.3580403652013358 3.0736699021056409e-06 0.020693094523689365 -0.58655063220394066 3.0736705643127693e-06 0.00017061729471622367 +4 500 1 15 1 5.8702825782132528 4.4693976428357729 8.3428186742278818 5.8739442971320459 5.5837864939537767e-06 0.018796068771134142 -1.0706467000377176 5.5837871561608746e-06 0.00030995210414437271 +4 500 1 15 3 5.8702825782601371 4.7098874141239913 6.8167957045207928 4.3859069671229562 3.9775195081876335e-06 0.013389073936722999 -2.5586840300819649 3.9775201703947493e-06 0.00022078935167331389 +4 500 1 15 5 5.8702825785273234 4.8735460119823859 5.9548480827837142 3.4772929254507421 3.0736699021056409e-06 0.010346547261844682 -3.4672980719545343 3.0736705643127693e-06 0.00017061729471622367 +4 500 2 15 1 4.8563641337472694 4.3103867659103585 4.781135635779564 2.1563139577946786 3.6850031690368115e-06 0.006202204638560499 -3.5668871649413814 3.6850056895078815e-06 0.00020455207824079277 +4 500 2 15 3 4.5564955803617426 4.3650348883150709 3.711881355241188 0.86352234233785541 1.4322220164880437e-06 0.0024105634721699417 -4.3140957427505944 1.432222529466955e-06 7.9501666914624203e-05 +4 500 2 15 5 4.3192648651884973 4.3192647263053008 3.036448972178853 7.1806364043691673e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326326901143 3.1036885691353279e-12 1.7228357308550252e-10 +4 500 4 15 1 4.0051745686255105 4.0050287756412137 3.0368155864825837 0.0004796939577117465 1.5621620535007706e-09 1.3146323476484488e-06 -4.0097544758321835 1.5626505833126274e-09 8.6741636597980988e-08 +4 500 4 15 3 4.1729334888883667 4.1729333291926638 3.0364487774738542 4.6368156880749467e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313121837811 4.0159515435019528e-12 2.2292265020826827e-10 +4 500 4 15 5 4.3192648651884973 4.3192647263053008 3.0364486973745968 3.590318917723323e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960329917218626 3.1036885691353279e-12 1.7228357308550252e-10 +4 900 0.5 15 1 5.8702825782132528 4.4693976428357729 13.185717640571141 9.9507027695248613 5.5837864939537767e-06 0.037592137542268284 3.0061117723550979 5.5837871561608746e-06 0.00030995210414437271 +4 900 0.5 15 3 5.8702825782601371 4.7098874141239913 10.434824816593402 7.815406050993067 3.9775195081876335e-06 0.026778147873445998 0.87081505378814583 3.9775201703947493e-06 0.00022078935167331389 +4 900 0.5 15 5 5.8702825785273234 4.8735460119823859 8.8018918053997481 6.3730049539106695 3.0736699021056409e-06 0.020693094523689365 -0.57158604349460695 3.0736705643127693e-06 0.00017061729471622367 +4 900 1 15 1 5.8702825782132528 4.4693976428357729 8.2830762785089043 5.8850294124181861 5.5837864939537767e-06 0.018796068771134142 -1.0595615847515774 5.5837871561608746e-06 0.00030995210414437271 +4 900 1 15 3 5.8702825782601371 4.7098874141239913 6.7855419764949385 4.3900378503937931 3.9775195081876335e-06 0.013389073936722999 -2.554553146811128 3.9775201703947493e-06 0.00022078935167331389 +4 900 1 15 5 5.8702825785273234 4.8735460119823859 5.9344272410723153 3.4793786629028034 3.0736699021056409e-06 0.010346547261844682 -3.465212334502473 3.0736705643127693e-06 0.00017061729471622367 +4 900 2 15 1 4.857856184044107 4.3107640975911483 4.7731740183004616 2.1594483969621301 3.6895256674024084e-06 0.006209816425865506 -3.5662679978213259 3.6895281917834511e-06 0.00020480311916644192 +4 900 2 15 3 4.5569937613003653 4.3652552236990925 3.7086286797008867 0.86458694622831989 1.4338592247349714e-06 0.0024133190466206524 -4.313999900177568 1.4338597897910465e-06 7.9592550085542404e-05 +4 900 2 15 5 4.3192648651884973 4.3192647263053008 3.0350365019205574 7.1809096136021822e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326326627939 3.1036885691353279e-12 1.7228357308550252e-10 +4 900 4 15 1 4.0051745686255105 4.0050287756412137 3.0354019141935389 0.00047971230368704099 1.5621620535007706e-09 1.3146323476484488e-06 -4.0097544574862081 1.5626505833126274e-09 8.6741636597980988e-08 +4 900 4 15 3 4.1729334888883667 4.1729333291926638 3.0350363078538862 4.6369916872901484e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313121661809 4.0159515435019528e-12 2.2292265020826827e-10 +4 900 4 15 5 4.3192648651884973 4.3192647263053008 3.0350362280172298 3.590454940027854e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960329917082611 3.1036885691353279e-12 1.7228357308550252e-10 +4 1500 0.5 15 1 5.8702825782132528 4.4693976428357729 13.122807197998259 9.9740486531383272 5.5837864939537767e-06 0.037592137542268284 3.0294576559685638 5.5837871561608746e-06 0.00030995210414437271 +4 1500 0.5 15 3 5.8702825782601371 4.7098874141239913 10.404249196708577 7.8234885630424138 3.9775195081876335e-06 0.026778147873445998 0.87889756583749268 3.9775201703947493e-06 0.00022078935167331389 +4 1500 0.5 15 5 5.8702825785273234 4.8735460119823859 8.7834535981536241 6.3767714254347707 3.0736699021056409e-06 0.020693094523689365 -0.5678195719705057 3.0736705643127693e-06 0.00017061729471622367 +4 1500 1 15 1 5.8702825782132528 4.4693976428357729 8.2676359682428373 5.8878943396996171 5.5837864939537767e-06 0.018796068771134142 -1.0566966574701464 5.5837871561608746e-06 0.00030995210414437271 +4 1500 1 15 3 5.8702825782601371 4.7098874141239913 6.7768662200959753 4.39118454677961 3.9775195081876335e-06 0.013389073936722999 -2.5534064504253111 3.9775201703947493e-06 0.00022078935167331389 +4 1500 1 15 5 5.8702825785273234 4.8735460119823859 5.9285442841392531 3.4799795344916244 3.0736699021056409e-06 0.010346547261844682 -3.464611462913652 3.0736705643127693e-06 0.00017061729471622367 +4 1500 2 15 1 4.8582940304503284 4.3108747300149357 4.7707467623666933 2.1603733238754277 3.690851638277215e-06 0.006212048158738743 -3.5660807923101503 3.6908541601978871e-06 0.00020487672274204202 +4 1500 2 15 3 4.5571482388002558 4.365323530523737 3.7076037754783036 0.8649174150202531 1.4343667775736364e-06 0.0024141733054708846 -4.3139697887237407 1.4343673590604204e-06 7.9620724899273962e-05 +4 1500 2 15 5 4.3192648651884973 4.3192647263053008 3.0345831060626614 7.1809975898950995e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326326539956 3.1036885691353279e-12 1.7228357308550252e-10 +4 1500 4 15 1 4.0051745686255105 4.0050287756412137 3.0349481379325289 0.0004797181926101679 1.5621620535007706e-09 1.3146323476484488e-06 -4.0097544515972849 1.5626505833126274e-09 8.6741636597980988e-08 +4 1500 4 15 3 4.1729334888883667 4.1729333291926638 3.0345829121980019 4.6370484574342896e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313121605037 4.0159515435019528e-12 2.2292265020826827e-10 +4 1500 4 15 5 4.3192648651884973 4.3192647263053008 3.0345828324444506 3.5904988737733845e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960329917038672 3.1036885691353279e-12 1.7228357308550252e-10 +6 100 0.5 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 0.5 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 0.5 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 1 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 1 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 1 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 2 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 2 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 2 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 4 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 4 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 100 4 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 0.5 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 0.5 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 0.5 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 1 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 1 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 1 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 2 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 2 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 2 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 4 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 4 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 500 4 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 0.5 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 0.5 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 0.5 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 1 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 1 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 1 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 2 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 2 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 2 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 4 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 4 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 900 4 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 0.5 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 0.5 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 0.5 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 1 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 1 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 1 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 2 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 2 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 2 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 4 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 4 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +6 1500 4 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 +0.5 100 0.5 25 1 1.4064315157230882 1.1397291800324882 33.535719423557353 3.4216414573490117 7.9644452142332409e-06 0.053619621786311598 3.3030570555526011 7.9644455320981397e-06 0.00044210077891191453 +0.5 100 0.5 25 3 1.5954124971659938 1.4018117298270372 31.191249087006778 3.2939585898339492 5.626586940336478e-06 0.037880286143406806 3.1008759409911337 5.6265870700498372e-06 0.00031232789731056547 +0.5 100 0.5 25 5 1.7452545545113238 1.5881353349338942 29.262213724659755 3.1770775521522618 4.4519911133823881e-06 0.029972468046986948 2.9051006149550638 4.4519915504116376e-06 0.00024712692480775118 +0.5 100 1 25 1 1.5932824843611644 1.2671223542432735 29.879407846846796 3.2157448245139046 9.5619590523274174e-06 0.032187340996817596 3.023650171377644 9.5619591422393007e-06 0.00053077763764858732 +0.5 100 1 25 3 1.7920899362273437 1.5523575254639288 26.688926403109683 3.0013314142961085 6.7853474838497329e-06 0.022840747596739566 2.7006930858511775 6.7853474843817848e-06 0.00037664987423712378 +0.5 100 1 25 5 1.9404992363787317 1.7453156059561379 24.22920998828554 2.8076762493713701 5.3575323613880757e-06 0.018034455081201134 2.402599334908301 5.357532576432653e-06 0.00029739287129795463 +0.5 100 2 25 1 1.7967548832244611 1.4030643672663468 24.763245420986252 2.8521396964186123 1.1266254056967917e-05 0.018962158230542741 2.5485370769014066 1.126625410728482e-05 0.000625381854414922 +0.5 100 2 25 3 1.974750501718451 1.6895987603563785 20.874909545225634 2.4917019650291854 7.8414037562845282e-06 0.013197815176578424 2.0594485162722274 7.8414043294004221e-06 0.00043527084814878831 +0.5 100 2 25 5 2.0812347115368164 1.8568575136921954 18.155583441976756 2.1776498358393557 5.9999663789796766e-06 0.010098504017471864 1.6531924903518367 5.9999667351424357e-06 0.00033305394033541135 +0.5 100 4 25 1 1.9478356888215389 1.5017496970624489 18.554034088544238 2.22758211566109 1.2503146687341704e-05 0.010521982047725396 1.8167837670905369 1.2503147133216513e-05 0.00069404091774723914 +0.5 100 4 25 3 2.0130156381644118 1.7179877325704682 14.788296988437251 1.6880916255969947 8.0598145297856256e-06 0.0067827104577008772 1.2240623501463719 8.0598148848335275e-06 0.00044739466471460052 +0.5 100 4 25 5 2.0063215670071219 1.7976840658200521 12.604399811198828 1.2879603966247419 5.6591721458135337e-06 0.0047624577406199832 0.82959875184286114 5.6591722813330852e-06 0.00031413667950780377 +0.5 500 0.5 25 1 2.4109901172055332 1.7891385804115791 26.953803399175349 13.96235023623394 1.6103335350584414e-05 0.10841367198476044 13.074476999673427 1.610333535121711e-05 0.00089388483770286482 +0.5 500 0.5 25 3 2.7164829891259941 2.210510814002963 23.551280527047581 12.950185456809166 1.1846365343788493e-05 0.079754158913824647 11.617786198957624 1.1846366710650622e-05 0.00065758349767697038 +0.5 500 0.5 25 5 2.9416567539754097 2.4917986705441106 21.156049380602255 12.089414780959613 9.6532721227130728e-06 0.064989435710501212 10.366287275475118 9.6532733143316879e-06 0.00053584642322129826 +0.5 500 1 25 1 2.7771547107039529 1.9960803050999476 20.778763228621415 11.939993582679428 1.8693644905798969e-05 0.06292630200188086 10.507323310430499 1.8693645986015445e-05 0.0010376711621435163 +0.5 500 1 25 3 3.0330102014270279 2.4086469007774403 17.044362096255803 10.197210725093214 1.3367901976215948e-05 0.044998856088571453 8.3018317586369506 1.3367901981828912e-05 0.00074204285216924299 +0.5 500 1 25 5 3.158329436174887 2.6343326757148198 14.72304159230254 8.7962094107062914 1.0472297472006299e-05 0.035251710230816372 6.6531341193001641 1.0472298027026705e-05 0.00058130990990989202 +0.5 500 2 25 1 2.9462904096973768 2.0844428808493811 14.248433530867084 8.4712366920423499 1.9799051423878981e-05 0.033323653453567317 6.73955249947117 1.979905230028143e-05 0.0010990314904402681 +0.5 500 2 25 3 2.9225815548173313 2.341499812224078 11.30988163184572 6.1265377221242154 1.2852392837172094e-05 0.021631777997126112 4.4384260644956619 1.2852394389878225e-05 0.00071342738772568553 +0.5 500 2 25 5 2.8331109150616167 2.4173177253909577 9.7364229966751275 4.6386409369409947 9.2251134932391925e-06 0.015526727949590972 3.1101510785484425 9.2251137575675636e-06 0.00051207958687580146 +0.5 500 4 25 1 2.6402150326898228 1.9210741314244792 9.583691352196416 4.4863829806344775 1.7755015392816997e-05 0.014941674915279099 3.2745250391091165 1.7755016415853437e-05 0.00098556849380257764 +0.5 500 4 25 3 2.436356190059195 2.0218974856044101 7.9399765537701912 2.7690999438141009 1.039695131715295e-05 0.0087495202484437189 1.8482539356547498 1.0396952294769349e-05 0.00057712752121950308 +0.5 500 4 25 5 2.2867611239124623 2.0165836351964481 7.1431380235951307 1.8887638024633597 6.9196285659173781e-06 0.0058231907029629715 1.1519511946939347 6.9196289469184526e-06 0.00038410374393108259 +0.5 900 0.5 25 1 2.7197604410447296 1.9650087070302305 26.048188942300413 16.972876943369247 1.8304847057311886e-05 0.12323507157978909 15.635159184548764 1.8304848479194313e-05 0.0010160892855506142 +0.5 900 0.5 25 3 3.0590453936785376 2.4241509568610997 22.789749720102563 15.426180066088692 1.3486909354637156e-05 0.090798914326078783 13.480384375876335 1.3486910990082746e-05 0.00074864895865016639 +0.5 900 0.5 25 5 3.2874061407846096 2.7150123329803253 20.561732192903435 14.127399787118666 1.0935682742199681e-05 0.073623103284576094 11.717131613072423 1.0935684088448819e-05 0.00060703214479316235 +0.5 900 1 25 1 3.0845830084812627 2.1529681238294636 19.97225367517332 13.746976172967521 2.0656004615744774e-05 0.069531971488309738 11.751181815336844 2.0656005529640243e-05 0.0011466003624557449 +0.5 900 1 25 3 3.2552167071314448 2.5367564606412776 16.514782254357918 11.199702974192943 1.435103216180415e-05 0.048308256009091888 8.8571004956490924 1.4351033237008327e-05 0.00079661577779674311 +0.5 900 1 25 5 3.3008316449748913 2.7232113254639621 14.362616300819928 9.3565169518213231 1.0982765970949394e-05 0.036970042588620779 6.9178393586801477 1.098276621059857e-05 0.00060964564033297644 +0.5 900 2 25 1 3.0506148929043064 2.1364568870268736 13.845359547567909 8.8865087986354219 2.0449544585256871e-05 0.034418494222430041 6.9571008272649895 2.0449545713341029e-05 0.0011351399230275342 +0.5 900 2 25 3 2.9571261757000715 2.3627422523318664 11.116998278664372 6.2459967177706446 1.3015493666290431e-05 0.021906291931716625 4.4942259627744088 1.3015493821534228e-05 0.00072248092264969347 +0.5 900 2 25 5 2.8486017197899756 2.4280650238119645 9.6208634276290592 4.6875406037722005 9.2869014270008387e-06 0.015630722815213764 3.1319705838605385 9.2869027021054791e-06 0.00051550944779936046 +0.5 900 4 25 1 2.6522498945103816 1.9277849481905902 9.4686138378274389 4.5246599673937009 1.7839005529437774e-05 0.015012356539018229 3.2941949963470161 1.7839006888533584e-05 0.00099023074596356277 +0.5 900 4 25 3 2.4404897779943857 2.024760580173147 7.8817725565408985 2.779999416306842 1.0418959521537938e-05 0.0087680411805924202 1.8537118747795414 1.0418960614863627e-05 0.00057834918761385666 +0.5 900 4 25 5 2.2889167997028066 2.0182367568796988 7.104156810751137 1.8936052214909669 6.9291447675928974e-06 0.0058311990312419418 1.1543186116999431 6.9291452468913483e-06 0.00038463198706030244 +0.5 1500 0.5 25 1 2.8799224461320576 2.0503524385318008 25.954225797283243 18.083941475864044 1.9372632441163001e-05 0.13042380185427568 16.472899690884777 1.9372633102666599e-05 0.0010753612602090812 +0.5 1500 0.5 25 3 3.1949269863757976 2.5029592249071397 22.736487599463157 16.167837514687879 1.4091719930031613e-05 0.09487072515943816 13.950159453241419 1.4091721595786878e-05 0.00078222157067926051 +0.5 1500 0.5 25 5 3.3913677928808559 2.7775205859597101 20.515385285153567 14.625846867062334 1.1294588890250277e-05 0.076039393609589986 11.992938265924771 1.129458987745448e-05 0.00062695475311987125 +0.5 1500 1 25 1 3.1648920581658313 2.1911568882113492 19.864151222823185 14.140651868278095 2.1133465216675298e-05 0.071139193093275252 11.984270231861251 2.1133465338826824e-05 0.0011731038211949389 +0.5 1500 1 25 3 3.2906228580062979 2.5562593578329533 16.43739000070611 11.353759436344893 1.4500651566868332e-05 0.04881190288565633 8.9366942855090166 1.4500652643976951e-05 0.00080492104601592848 +0.5 1500 1 25 5 3.3195393624445213 2.7345742020513639 14.306787609947037 9.4325989070944978 1.1048013206774189e-05 0.0371896769770447 6.9541571676104139 1.1048013895297038e-05 0.00061326749349414585 +0.5 1500 2 25 1 3.0635838197967802 2.1427857609299483 13.785500844902149 8.9413159162123073 2.0528683289706206e-05 0.034551692056274411 6.9866737496745239 2.052868505482719e-05 0.0011395328923023698 +0.5 1500 2 25 3 2.9618081449919753 2.3656048925914748 11.084785084920613 6.2635218577554408 1.3037472107710882e-05 0.021943283702163831 4.5030388889266275 1.3037472113595314e-05 0.00072370092220900998 +0.5 1500 2 25 5 2.8510249480242815 2.4297427398960556 9.5996738299495945 4.695682014732073 9.2965467100300613e-06 0.015646956727750592 3.1358544373266799 9.2965480996743051e-06 0.00051604485704547908 +0.5 1500 4 25 1 2.6541517578136102 1.9288433975318224 9.4474987045381411 4.5311514478798482 1.785225255726609e-05 0.015023504531798029 3.2977317198105895 1.7852253912286929e-05 0.00099096607895014874 +0.5 1500 4 25 3 2.4412643230160742 2.0252968123574115 7.8698230574427983 2.782133934042252 1.0423081447688339e-05 0.0087715099740122773 1.8548246360396572 1.042308255613048e-05 0.00057857799367918292 +0.5 1500 4 25 5 2.289354797741475 2.0185725843241862 7.0957185814138359 1.8946193961025655 6.9310779545242413e-06 0.0058328258983574889 1.1548294759867179 6.9310784537894314e-06 0.00038473929801773141 +1 100 0.5 25 1 1.7067677422675573 1.4930281707158857 31.814968089542472 3.3293694751750693 6.1204428183868747e-06 0.041205108486422753 3.079478616621798 6.120443067641477e-06 0.00033974149695484193 +1 100 0.5 25 3 1.908653295271608 1.7475302694978256 29.229694115283259 3.1750053074436546 4.4356538379267522e-06 0.029862479402783016 2.7941409877644108 4.4356542987663469e-06 0.00024622005544081861 +1 100 0.5 25 5 2.068375804921013 1.934230807726961 27.174431901929609 3.0364186889892033 3.562265404120197e-06 0.023982502049237363 2.5237264989860471 3.5622654081506123e-06 0.00019773885140997015 +1 100 1 25 1 1.8835359299507122 1.6113739326199386 27.806772699616921 3.0807188758916921 7.6033437173373366e-06 0.025594275776194522 2.7182450053465459 7.6033442457142131e-06 0.0004220563000674001 +1 100 1 25 3 2.0885287736046294 1.8829566223176897 24.465021351498685 2.8274862180378979 5.4772310308385439e-06 0.018437383170453913 2.296277123205523 5.4772316440867064e-06 0.00030403728249162954 +1 100 1 25 5 2.2388019480971684 2.0692951954928329 21.960274612874279 2.6015049297934909 4.3397624225280723e-06 0.014608451278097276 1.9183960334204448 4.3397633766499712e-06 0.00024089721768803617 +1 100 2 25 1 2.065761371813625 1.7305459556739704 22.465479553262767 2.6500079481123886 9.096084858167948e-06 0.015309560701087582 2.1396863753071385 9.0960848615259338e-06 0.00050491728345966884 +1 100 2 25 3 2.229326921845507 1.9869199694248711 18.593144050229022 2.2324047126725732 6.2765539131840105e-06 0.010564026680253866 1.5596038030372326 6.2765547148437753e-06 0.00034840714487059535 +1 100 2 25 5 2.3160596725377869 2.1296644210692173 15.953774192781461 1.8726535534532811 4.6871811403286466e-06 0.0078889638018732507 1.1017719369442722 4.6871820554767758e-06 0.00026018218459488069 +1 100 4 25 1 2.1570011067485102 1.7889790884374803 16.347339656953643 1.9311024117334257 9.8278048966268909e-06 0.0082705569467202249 1.3337288228517736 9.8278055398232398e-06 0.00054553458450309412 +1 100 4 25 3 2.172736320311301 1.9453684013868573 12.876814755737477 1.3422870152503665 5.9571140410287759e-06 0.0050131897644147541 0.7289913010853516 5.957114924354615e-06 0.00033067526640880463 +1 100 4 25 5 2.1290557326235366 1.9826006659667021 10.954293541487257 0.92675631179459028 3.8407392511293916e-06 0.0032321615078939612 0.35699674854767616 3.840739357933232e-06 0.00021319674482005174 +1 500 0.5 25 1 2.7152256348729877 2.1241858001256579 25.464804436225535 13.545571354735634 1.402224907889137e-05 0.094403021425767411 12.215209474738369 1.4022250411574108e-05 0.00077836527402576231 +1 500 0.5 25 3 3.035805875669717 2.5343813119374463 22.121162872843342 12.453593419118651 1.0480853321201807e-05 0.070561021636050256 10.552828035611192 1.0480853402337577e-05 0.00058178481278587713 +1 500 0.5 25 5 3.2714972563656546 2.8125569558448102 19.829090633916422 11.544687301949235 8.6118791039231962e-06 0.05797838870139773 9.167942008783232 8.6118810868372665e-06 0.00047803947193101676 +1 500 1 25 1 3.0692158668619798 2.3123650617248628 19.251243270473637 11.28963717944057 1.6374163783621359e-05 0.055118495107221555 9.3239932073480407 1.6374165540780969e-05 0.00090891843135059499 +1 500 1 25 3 3.3073938746229428 2.6945336682085506 15.732686650722133 9.4420256633549435 1.1708862404537072e-05 0.039414218868456571 6.9894229362945355 1.1708862402854945e-05 0.00064995073010574219 +1 500 1 25 5 3.4070871781761753 2.8968799833242369 13.576633462760762 7.9864201400500843 9.0956811562017521e-06 0.03061776246591786 5.3193551702314501 9.0956832275089874e-06 0.0005048949890374126 +1 500 2 25 1 3.1413635735369425 2.3480117351669367 12.999010208695836 7.5455276369579689 1.6819425171713963e-05 0.028308664072381824 5.4367043667830455 1.6819426904326606e-05 0.00093363457698177109 +1 500 2 25 3 3.062141766165432 2.5505311945440359 10.338947585502243 5.2261867652917946 1.0604729349280254e-05 0.017848750338517717 3.2743573499459844 1.0604731085965469e-05 0.00058866117601806653 +1 500 2 25 5 2.9434589272259224 2.593903629993414 8.9104733396616336 3.7999726760580361 7.3564380737870968e-06 0.012381572620587781 2.073519555117354 7.3564391483246717e-06 0.00040835077148624325 +1 500 4 25 1 2.7261277399387702 2.1302922749371764 8.773502327045108 3.6573638213630395 1.4098603690961561e-05 0.011864633651341433 2.3092812369319966 1.4098605073228007e-05 0.0007826036676784905 +1 500 4 25 3 2.4954622287011667 2.1775680412556895 7.3327904819707905 2.1009467196346536 7.7416621761021547e-06 0.0065149703889317732 1.1004735807472374 7.7416627394189056e-06 0.0004297342625267225 +1 500 4 25 5 2.3314278361602039 2.1416036255756463 6.6399870006979089 1.3180326577846722 4.7558831455861534e-06 0.0040022978479169226 0.5288968274739948 4.7558834491892204e-06 0.00026399575071824706 +1 900 0.5 25 1 3.0369913612965367 2.2961354722933662 24.742429827264274 16.398047102611969 1.6171413488520494e-05 0.10887199945263296 14.494995645437719 1.6171413622583404e-05 0.00089766381474234828 +1 900 0.5 25 3 3.3865464507156968 2.7384158494852802 21.578426575077408 14.746811577469545 1.2045161796821869e-05 0.081092530933141255 12.124355120461686 1.2045162333402272e-05 0.00066861850310309591 +1 900 0.5 25 5 3.6170247196088368 3.0196356678278651 19.440314062236823 13.390099586425803 9.7996047382133619e-06 0.065974601567892657 10.257496764667584 9.7996070277024083e-06 0.00054396930489605377 +1 900 1 25 1 3.3576561041771913 2.4489754226298484 18.643176569034416 12.83115003746013 1.8080071770368084e-05 0.060860900170674165 10.271078878653658 1.8080073047062817e-05 0.0010036121591486438 +1 900 1 25 3 3.4939022296603972 2.7957986590234949 15.351061741426308 10.226068716717712 1.248480356792383e-05 0.042026181823194148 7.3683871871339859 1.2484805059482584e-05 0.00069302276211393745 +1 900 1 25 5 3.5175050865725619 2.9626679840723025 13.319678229798109 8.3986029508113393 9.4729928860268937e-06 0.031887864256097027 5.4885831070771083 9.4729929558933188e-06 0.00052583918711592112 +1 900 2 25 1 3.2141137764500574 2.3829721951774081 12.713361318629971 7.8232946939695225 1.7256029291685077e-05 0.02904350960002007 5.5661264432551079 1.7256030895840091e-05 0.00095787015797058517 +1 900 2 25 3 3.0850088484570333 2.5644496204877036 10.202963924130579 5.3029982091841674 1.0711483748788707e-05 0.01802842796739507 3.3063656271131698 1.0711484629114369e-05 0.0005945869902367121 +1 900 2 25 5 2.9537152220507399 2.601027572464881 8.8284794052283146 3.8311895802719165 7.3973620357422593e-06 0.012450451472253172 2.0857533745107304 7.397362385864237e-06 0.00041062239166606923 +1 900 4 25 1 2.7339377312023632 2.1346552593160761 8.6916421140633435 3.6811405151422663 1.415315689711806e-05 0.011910542722887853 2.3202866368106414 1.4153157986835286e-05 0.00078563186160617742 +1 900 4 25 3 2.4982141815821537 2.1794945706983837 7.2903162841984859 2.1077000742102197 7.7564622167500938e-06 0.0065274253145514872 1.1034243993060164 7.756462928719499e-06 0.00043055581064221476 +1 900 4 25 5 2.3328579649223835 2.1427134553086864 6.6112464997307274 1.3209395530578538 4.7622693365955081e-06 0.0040076721259954002 0.53009157560945619 4.7622695795766041e-06 0.0002643502403317571 +1 1500 0.5 25 1 3.1922321281105304 2.3725620315680356 24.718912385147345 17.392810431699328 1.7126031006807495e-05 0.11529884136117691 15.18065839014611 1.7126032506810799e-05 0.00095065403867947824 +1 1500 0.5 25 3 3.5096072720630076 2.8039824620169203 21.562678360526306 15.374946328460103 1.2547494229338257e-05 0.084474420608820294 12.482461499737438 1.2547494363246552e-05 0.00069650260134590915 +1 1500 0.5 25 5 3.7077555968398088 3.0695766904607504 19.415464149517739 13.797877140788749 1.0085848099201465e-05 0.067901698853664164 10.460422636202752 1.0085848982686199e-05 0.00055985839482021644 +1 1500 1 25 1 3.4204858310939494 2.4765947659114316 18.560857698339614 13.126198050673592 1.8424799466556563e-05 0.062021318014710544 10.429927136724768 1.8424801254322564e-05 0.0010227477798680302 +1 1500 1 25 3 3.5205658442244991 2.8096606660018448 15.291513696850064 10.337957445055922 1.2590988395402126e-05 0.042383619795060404 7.4211362390016227 1.2590988643793438e-05 0.00069891693831770408 +1 1500 1 25 5 3.5317723269039187 2.9709726723850061 13.277169491194476 8.4542692824670933 9.5206114979305644e-06 0.032048157402172102 5.5125192302727708 9.5206127987523838e-06 0.00052848253115472571 +1 1500 2 25 1 3.2232424539819684 2.3872881801530794 12.668411979997003 7.8606563820005171 1.7309924190410612e-05 0.029134219750198215 5.5846108764109701 1.7309925102441205e-05 0.00096086178753489898 +1 1500 2 25 3 3.0883892201068082 2.5664988442623313 10.178702088130448 5.3151035915638616 1.0727200836060113e-05 0.018054881293785251 3.3118119009813518 1.0727201449678981e-05 0.00059545941991001833 +1 1500 2 25 5 2.9554596970564115 2.6022375437705394 8.8125274152766586 3.8367518445415016 7.4043126539915635e-06 0.012462150012191732 2.0880772646025503 7.4043128977633453e-06 0.0004110082097009906 +1 1500 4 25 1 2.7352812917992591 2.1354048537076493 8.6757067600129023 3.6854531281240157 1.4162529467508085e-05 0.011918430178730047 2.322395761012662 1.4162530485401433e-05 0.00078615212242028499 +1 1500 4 25 3 2.4987631019842627 2.1798787295983111 7.2812223862232885 2.1090882162638973 7.7594134017956244e-06 0.0065299088746380079 1.1040530552521008 7.7594141425531943e-06 0.00043071963044980259 +1 1500 4 25 5 2.3331635051203539 2.1429505383645338 6.6048151108982829 1.3215724696996087 4.7636335585048049e-06 0.0040088201824645181 0.53035840317157845 4.7636337889766626e-06 0.00026442596663761657 +2 100 0.5 25 1 2.4704409560027627 2.3109040793539894 27.864790208576487 3.0847067213104089 3.824791973188767e-06 0.025749929027975127 2.1184190402609073 3.8247922595087756e-06 0.00021231153258444496 +2 100 0.5 25 3 2.6821993311383823 2.5512710143277415 25.127782290595782 2.8816849389225179 2.9154929167692038e-06 0.019628187941887327 1.6042391526372659 2.9154930173534269e-06 0.00016183697015561627 +2 100 0.5 25 5 2.8509855879492738 2.735486416901832 23.085569152493164 2.7074341653496146 2.4084727913981762e-06 0.01621473896594882 1.1476757888076996 2.4084741793784216e-06 0.00013369271048450855 +2 100 1 25 1 2.6100156394027958 2.397790170751485 23.291015323167962 2.7259697192257728 4.9095556873461843e-06 0.016526481883752976 1.5601118072929787 4.9095559196940243e-06 0.00027252600164829444 +2 100 1 25 3 2.8082784927398938 2.6402594720555435 19.973239446667055 2.3941655506633768 3.5976150896033781e-06 0.01211024467168941 0.90858838838593825 3.5976159030017058e-06 0.00019970113255629785 +2 100 1 25 5 2.9480523443568321 2.8079203768044358 17.584829690510492 2.1034901218696693 2.8240322880430286e-06 0.0095062204035624917 0.36854709614734471 2.82403303634158e-06 0.00015676009083217209 +2 100 2 25 1 2.712595930747344 2.4599365619557996 17.64556056679524 2.1115336906467768 5.6850652148631124e-06 0.009568495935746834 0.78542751852611947 5.6850664542705428e-06 0.00031557404686486501 +2 100 2 25 3 2.8117431942213011 2.6426730270030294 14.040344791445145 1.5596941651672354 3.6161109500043962e-06 0.0060862525970442755 0.068166761765579231 3.616111532962547e-06 0.00020072781198792933 +2 100 2 25 5 2.8304537502797467 2.719997127712662 11.674770130440052 1.0916494104229488 2.3195885757322019e-06 0.0039040843017018553 -0.43221921738695168 2.3195887026395502e-06 0.00012875874008545936 +2 100 4 25 1 2.6076015233890186 2.3963096166450253 11.903653325502439 1.1416239167871969 4.8910761097506907e-06 0.0041160690430799918 -0.020599632298418102 4.8910764658744304e-06 0.00027150022014290481 +2 100 4 25 3 2.4903264302105312 2.4118727410394039 9.2084082334114274 0.47228012178541023 1.8462850009310341e-06 0.0015537350813014652 -0.52111917684090359 1.8462852906314161e-06 0.00010248600003504946 +2 100 4 25 5 2.362181249757271 2.3533606344612839 7.8634321681794095 0.057021658155842037 2.1358540125426123e-07 0.00017974209323871968 -0.7694374281382208 2.1358611617419419e-07 1.1856015330235592e-05 +2 500 0.5 25 1 3.4819575298678949 2.8696986466766958 22.461253229084171 12.576122885280533 1.0789204948889131e-05 0.072636960035907736 9.744850709349052 1.0789207105251822e-05 0.00059890131031095325 +2 500 0.5 25 3 3.8395770305726988 3.2612194505212155 19.469718513045258 11.387429236689602 8.3458776851062885e-06 0.056187567735475882 7.7510281358166164 8.3458792359561454e-06 0.00046327389597314159 +2 500 0.5 25 5 4.1100266689605318 3.5360870702229903 17.513011346189415 10.446487742119256 6.9900491021178888e-06 0.047059622992132226 6.202819001663201 6.9900512255430665e-06 0.00038801283516753075 +2 500 1 25 1 3.7816796621496387 2.9978937235432248 16.271832091163958 9.7632232603743709 1.2382269085228115e-05 0.041681031593999648 6.258169554746102 1.2382269495624353e-05 0.00068733108496388305 +2 500 1 25 3 3.9593833143631572 3.318190783682232 13.311529166708752 7.7868653503434366 8.7803170485033981e-06 0.029556187947862033 3.8795338797563659 8.7803195330332478e-06 0.00048738937180312233 +2 500 1 25 5 3.9981502429048379 3.4796062195553077 11.517143349619399 6.3109370845151229 6.6677841192955336e-06 0.022445007342788349 2.3164561766601923 6.66778413464234e-06 0.00037012401524520342 +2 500 2 25 1 3.5651786682825946 2.9071999644587345 10.621286290709744 5.4940657159362551 1.1255435207671125e-05 0.018943949096326448 2.4777684113847736 1.1255436519412007e-05 0.00062478137770813249 +2 500 2 25 3 3.3789229920756125 3.0105977683443332 8.4971557653818728 3.3667082756022455 6.4321615003289102e-06 0.010825928788478528 0.76075508296540262 6.432161538890734e-06 0.00035704477040747901 +2 500 2 25 5 3.198688118828958 2.9882494321805666 7.3267885336594123 2.0942568071790348 3.8577966509517737e-06 0.0064930322134323327 -0.1311422695237896 3.8577984840195662e-06 0.00021414368493031177 +2 500 4 25 1 2.9193741078636553 2.5803514250031343 7.204849352922424 1.9579853501404143 7.1867249367511624e-06 0.00604796477697835 0.27572823838314386 7.1867263640706507e-06 0.0003989301340033667 +2 500 4 25 3 2.6291525126438855 2.5131871721753614 6.1383480404337547 0.7379923310491594 2.6234628729014484e-06 0.002207766568034405 -0.45690009670396314 2.6234632522882945e-06 0.00014562660295799581 +2 500 4 25 5 2.4309429891018746 2.4085954956345947 5.6403935829542213 0.15159583021147194 5.3109264939455165e-07 0.00044693927555579914 -0.76215310850824491 5.3109340144785139e-07 2.9480621784504654e-05 +2 900 0.5 25 1 3.8400913328934534 3.0206380684959999 22.113761267636939 15.054715889153814 1.2664695987234463e-05 0.085263466645555494 11.417148519612585 1.2664697485989271e-05 0.00070300846439018991 +2 900 0.5 25 3 4.2155296484543321 3.4279871005681599 19.252128048114827 13.260753280719838 9.6169169198817091e-06 0.064744678897773231 8.7863422413163033 9.6169178233486787e-06 0.00053382835544538881 +2 900 0.5 25 5 4.4671370807611188 3.6938373088280572 17.359386275876343 11.870832180526506 7.8892223865953806e-06 0.053113193597135171 6.8700173900688819 7.8892232078936594e-06 0.00043792524051588453 +2 900 1 25 1 4.0087136466677755 3.0821516859478084 15.947993489155504 10.732430623985156 1.3428206183219658e-05 0.045201851318288383 6.7142641994308896 1.3428207050937252e-05 0.00074539034420967256 +2 900 1 25 3 4.0766946476387895 3.3705219524662304 13.110722600481111 8.2018404319118865 9.1791698954489036e-06 0.030898801163619496 4.0319955655499973 9.1791706681837173e-06 0.00050952931824500239 +2 900 1 25 5 4.0612083310013345 3.511847824527802 11.383486050822826 6.5155059423715898 6.8517678846531879e-06 0.023064331077708954 2.3800899622217413 6.8517680189574251e-06 0.00038033683147140854 +2 900 2 25 1 3.5950876308832083 2.9203230867281595 10.487044292254941 5.5991531654660385 1.1418547459418835e-05 0.019218482256269463 2.5158434915102319 1.1418548219811386e-05 0.00063383559366147026 +2 900 2 25 3 3.3882916202523394 3.0161645842149234 8.4330807942121737 3.3958725913161429 6.4747113015510934e-06 0.010897544079539195 0.7696341207654056 6.4747119968288725e-06 0.00035940671644900765 +2 900 2 25 5 3.2028165788824521 2.9911313493716256 7.2885559865986647 2.1056812201890178 3.8743078577051985e-06 0.0065208221171086126 -0.12820430355900836 3.8743097759752016e-06 0.00021506021515266176 +2 900 4 25 1 2.9222895808709417 2.5819998646394193 7.166865607347205 1.9658577398729884 7.2072727491900629e-06 0.0060652567210791918 0.27827941998063221 7.2072742925656951e-06 0.00040007073508552292 +2 900 4 25 3 2.6301268350610636 2.5138899336647542 6.1184384215655232 0.73994318226054379 2.6288522000538545e-06 0.0022123019386067065 -0.45643814171370156 2.6288526364490237e-06 0.00014592576388837211 +2 900 4 25 5 2.4313786076646746 2.4089440918230176 5.6271233468864565 0.15222650441552532 5.3309622897031711e-07 0.00044862538137016475 -0.76209234372015866 5.3309700155554493e-07 2.959184021956952e-05 +2 1500 0.5 25 1 3.9803812658593372 3.0722462266911599 22.154006949312173 15.78061470379628 1.3305292457998546e-05 0.089576201501039454 11.826037199126354 1.330529373406011e-05 0.00073856751229864608 +2 1500 0.5 25 3 4.3157965927420481 3.4664693846305616 19.247513520586818 13.6678115734312 9.9099182435240381e-06 0.066717273313830469 8.9790918596189435 9.9099204815103372e-06 0.00055009272725563903 +2 1500 0.5 25 5 4.539487477635439 3.7215752567027653 17.335640714614101 12.12121336341187 8.0471830062666055e-06 0.054176643524415244 6.9767843417955504 8.0471834659582436e-06 0.00044669350352252257 +2 1500 1 25 1 4.0443287814229798 3.0943574999267689 15.894511443475128 10.877600995328757 1.3579644797175919e-05 0.045711621991935972 6.7797983420985535 1.3579646613004726e-05 0.0007537966479602956 +2 1500 1 25 3 4.0921737820958475 3.3771694416063567 13.074744689859084 8.258131398878831 9.2298189627766387e-06 0.031069295388947912 4.0539542774071071 9.2298212946844988e-06 0.00051234089895556474 +2 1500 1 25 5 4.069914831589597 3.5162171193496432 11.358394947369653 6.5449449381217217 6.8766966891728971e-06 0.023148246092124704 2.3901631425650685 6.8766968339467918e-06 0.00038172061248663844 +2 1500 2 25 1 3.599439433657535 2.9222168031323053 10.462878037850402 5.6152881633934335 1.1442082939030142e-05 0.019258094667472393 2.5222089124548823 1.1442084147087298e-05 0.00063514205645780176 +2 1500 2 25 3 3.3899632735757614 3.0171559482354615 8.4201371739503887 3.4012407792525292 6.4822885296522992e-06 0.010910297262405253 0.77137820461729234 6.4822893827223713e-06 0.00035982733181917132 +2 1500 2 25 5 3.2036437587982807 2.9917084046253093 7.2802879741231701 2.1080107398202292 3.8776139227280708e-06 0.0065263865334414233 -0.12757655630205411 3.877615844945832e-06 0.00021524373271972422 +2 1500 4 25 1 2.9228794904180022 2.5823332322536849 7.1586329598464111 1.9674843762769045 7.2114281525988563e-06 0.006068753687175946 0.2788284088127011 7.2114297143772245e-06 0.00040030139963237438 +2 1500 4 25 3 2.630345725825717 2.514047799134147 6.1138366389006169 0.74038448443308091 2.6300628334363238e-06 0.0022133207431552933 -0.4563314758904724 2.6300632828359978e-06 0.0001459929660192061 +2 1500 4 25 5 2.4314815681278636 2.4090264816395592 5.6239655893117853 0.15237572180820846 5.3356976947499669e-07 0.00044902388782727556 -0.76207785814843199 5.3357054686414518e-07 2.9618126387129905e-05 +3 100 0.5 25 1 3.3894032063216408 3.2245052025538747 24.395376810110989 2.8216649025452747 2.7207796984814003e-06 0.018317305784931882 0.19301669354489448 2.7207804983011643e-06 0.00015102861494871854 +3 100 0.5 25 3 3.6058183243270427 3.4569133888498467 21.965340136022029 2.6019991807901666 2.1709030453066028e-06 0.014615330646768537 -0.50540858674934963 2.170904846423881e-06 0.00012050540363163369 +3 100 0.5 25 5 3.7828784911723914 3.6413779563211923 20.256286022347489 2.4254372519838294 1.848427499209952e-06 0.012444304749555263 -1.0823364562504527 1.8484278099483304e-06 0.00010260492977787013 +3 100 1 25 1 3.4919712238890019 3.2781663236001766 19.346535968457804 2.3226814269278209 3.3842930994222709e-06 0.011392162989629936 -0.53072708180788064 3.3842947506628704e-06 0.00018785982518250739 +3 100 1 25 3 3.6736771812209419 3.4978767114442935 16.434188869341043 1.9437542056510844 2.4821623124058188e-06 0.0083554221809189633 -1.3166050041277551 2.4821640663327993e-06 0.00013778318436485148 +3 100 1 25 5 3.7984887317106959 3.6514232103499729 14.393865899085538 1.6214166636735459 1.9055565447079289e-06 0.0064144594175293479 -1.9217758768375748 1.9055570150683615e-06 0.00010577613183837699 +3 100 2 25 1 3.4687248925417826 3.2661982843419288 13.348160303815607 1.4331194765225499 3.2363570231902759e-06 0.005447091256237685 -1.3689598101589016 3.2363587880728021e-06 0.00017964800377867344 +3 100 2 25 3 3.4661293132423152 3.3693394982157336 10.215758390722575 0.74472064563344142 1.504901472614064e-06 0.0025328897875719122 -2.0516405866507448 1.5049030334351141e-06 8.3536110654183415e-05 +3 100 2 25 5 3.3879847023515448 3.3692298143457196 8.1701879821943226 0.15754211678273911 2.9789541733650987e-07 0.00050138582097701318 -2.468031112893958 2.9789608413502247e-07 1.6536002449904106e-05 +3 100 4 25 1 3.0587357978664129 3.0372799024756612 8.0137425520274697 0.10673619974829762 4.0167936598268576e-07 0.00033803195175582858 -1.8384566349724119 4.0168098842366742e-07 2.2297029609973212e-05 +3 100 4 25 3 3.1718079687688916 3.1718075251234743 7.6943188555106987 2.1029354733137495e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704362845848699 7.8605668043621887e-12 4.3633454367816762e-10 +3 100 4 25 5 3.3170442487608387 3.3170439012574113 7.6943171755844508 1.5306961840266808e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731250224273484 6.1738007589111003e-12 3.4270334492984183e-10 +3 500 0.5 25 1 4.5555449297032249 3.6945550278102952 19.69550030743509 11.486742857939404 8.5122787015784824e-06 0.057307841568504672 6.3109739407587977 8.5122791194975708e-06 0.00047251063666375637 +3 500 0.5 25 3 5.019011136114008 4.0642255866232802 17.169576317069865 10.264808786022385 6.7651607547216718e-06 0.045545590588470991 4.2797884468497616 6.7651614474186194e-06 0.00037552936149978458 +3 500 0.5 25 5 5.401274999154448 4.3244488262832501 15.50351450134565 9.3006482910306243 5.7128216916137531e-06 0.038460850718081876 2.8011060012251487 5.7128236367345905e-06 0.00031711482857255569 +3 500 1 25 1 4.7226064225088908 3.736698384461282 13.520658263929683 7.9446780912020216 9.0290143691780389e-06 0.030393349602889318 2.4552127559125809 9.0290169108722415e-06 0.00050119438861350222 +3 500 1 25 3 4.818006888517318 4.0098279512101929 11.249249197695573 6.0720636190989605 6.3556261997680679e-06 0.021394225453250551 0.41423067585717366 6.3556264065340221e-06 0.00035279635895276281 +3 500 1 25 5 4.8169823166297228 4.1629844925990511 9.9037470591463332 4.8039251878274207 4.803469430406891e-06 0.016169375718740699 -0.8521431404228581 4.8034697136861792e-06 0.0002666372308457496 +3 500 2 25 1 4.0665427978557656 3.535578507666441 8.5540935181107169 3.4269115472412435 6.5590357187639538e-06 0.011039469952487146 -0.72037277251076182 6.5590357235393206e-06 0.00036408746730720625 +3 500 2 25 3 3.7893776749063957 3.5652129601639646 6.9269447245470896 1.6449101307943037 2.9934298030041625e-06 0.005038222046970563 -1.8776097534579179 2.9934298027090635e-06 0.00016616318638407236 +3 500 2 25 5 3.538251302398741 3.4766523548650303 5.948069739794434 0.51515468472516734 9.1053603490881845e-07 0.0015325172218953779 -2.4410265380679164 9.1053789206522982e-07 5.054331901555536e-05 +3 500 4 25 1 3.157309522397473 3.0952482381147961 5.7812143625577033 0.31848745187610028 1.1203634913581655e-06 0.00094283821807291833 -1.8225227120380025 1.1203641276924747e-06 6.2190626016790163e-05 +3 500 4 25 3 3.1718079687688916 3.1718075251234743 5.5130832403453356 2.2449228223031525e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704361425975209 7.8605668043621887e-12 4.3633454367816762e-10 +3 500 4 25 5 3.3170442487608387 3.3170439012574113 5.5130827284672623 1.6340505599732325e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731249190729727 6.1738007589111003e-12 3.4270334492984183e-10 +3 900 0.5 25 1 5.0180268979520628 3.7975432254481181 19.414320713718364 13.372329713539733 9.7742423268233092e-06 0.065803852335555274 7.3888176534234447 9.7742431207051999e-06 0.000542561372228987 +3 900 0.5 25 3 5.4764967900577117 4.1545432442363115 16.837175216979769 11.459480812134075 7.4441419862142164e-06 0.050116745998966122 4.8752705475890803 7.4441440500492583e-06 0.00041321920899524054 +3 900 0.5 25 5 5.8013296835189756 4.3899086998182701 15.142197599915233 10.045517058902471 6.0806610056497369e-06 0.040937282455159818 3.1545204535688427 6.0806616927652049e-06 0.00033753326076964779 +3 900 1 25 1 4.8734291863811237 3.7698435644914516 13.292840633749904 8.3734206660446588 9.4350984453695764e-06 0.03176030448757617 2.6215751874561031 9.4351000075474842e-06 0.00052373577616139243 +3 900 1 25 3 4.8869358839289037 4.0295932422127958 11.114453699186406 6.2434114337188404 6.5044801661743791e-06 0.021895295720256409 0.46908712873083402 6.5044803683623574e-06 0.00036105913784970068 +3 900 1 25 5 4.8560864385969378 4.1766471491000363 9.8160561643274171 4.895207274063889 4.880522567915532e-06 0.016428750978380788 -0.8275254869662465 4.8805250855580214e-06 0.00027091452043064235 +3 900 2 25 1 4.0779921658897864 3.5399325165795843 8.4925319274631992 3.4616662034496559 6.6126098969010122e-06 0.011129640299948632 -0.71105967378371071 6.6126108170789102e-06 0.00036706138312955371 +3 900 2 25 3 3.7930920923102871 3.5673209441121259 6.8980269783821555 1.6551466837878888 3.0094270994827301e-06 0.0050651469916374991 -1.8758010740809179 3.009427173071153e-06 0.00016705118917963659 +3 900 2 25 5 3.539581228930027 3.4775830854946932 5.9323935238326548 0.51839440674236137 9.1584062613583674e-07 0.0015414453445603254 -2.4407507266674298 9.1584257229544153e-07 5.0837778090227118e-05 +3 900 4 25 1 3.1580369882024693 3.0956695037773008 5.7667430395944201 0.32010689149219473 1.1255842805948365e-06 0.00094723175611553161 -1.8223761710063466 1.1255848587270416e-06 6.2480425130560175e-05 +3 900 4 25 3 3.1718079687688916 3.1718075251234743 5.501017589818554 2.2457082262672401e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704361418121172 7.8605668043621887e-12 4.3633454367816762e-10 +3 900 4 25 5 3.3170442487608387 3.3170439012574113 5.5010170845183026 1.6346222411200984e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731249185012913 6.1738007589111003e-12 3.4270334492984183e-10 +3 1500 0.5 25 1 5.1494182070134897 3.81950343693725 19.374717677881137 13.766409613076235 1.004296649777694e-05 0.067613003886453485 7.5898737808376078 1.0042967914877269e-05 0.00055747809685691195 +3 1500 0.5 25 3 5.5617716200243139 4.166939115283478 16.766700224328499 11.63808802082629 7.537233499108101e-06 0.05074347285546648 4.9642657164494688 7.5372347801582334e-06 0.00041838661005596633 +3 1500 0.5 25 5 5.8599304454265715 4.3970860580591857 15.073470699689445 10.140055961175541 6.1209631836778935e-06 0.041208611780041406 3.2032698294063202 6.1209632217806186e-06 0.00033977037034585726 +3 1500 1 25 1 4.8932726257930463 3.7738744591851079 13.252120821424089 8.4300661532444945 9.4844653407145964e-06 0.031926482682413521 2.6452546968187036 9.4844653415601318e-06 0.0005264760111884614 +3 1500 1 25 3 4.8965574159141925 4.0322584819650604 11.089254423165663 6.2681372868433538 6.524548023622489e-06 0.02196284787847242 0.4779044273706603 6.5245481501016858e-06 0.00036217308632260258 +3 1500 1 25 5 4.8622783264717739 4.1787705810784024 9.7989158414594417 4.9100041069109857 4.8924967491253458e-06 0.016469058309927467 -0.82315490860440033 4.8924991748363476e-06 0.00027157919371836512 +3 1500 2 25 1 4.0800293882451921 3.5407040219402526 8.4800117793062864 3.468013019937215 6.6221024032753374e-06 0.011145617075100712 -0.70923515871034537 6.6221035600347774e-06 0.00036758831862529988 +3 1500 2 25 3 3.7938681865937283 3.5677609603479135 6.8915901715481622 1.6573053843264898 3.0127662561226404e-06 0.0050707671042536694 -1.8754033063923536 3.0127663692509844e-06 0.00016723654561482011 +3 1500 2 25 5 3.5398865359872871 3.4777966989329334 5.9287168384284215 0.51913954723160782 9.170580842527024e-07 0.0015434944403231524 -2.4406860804586836 9.1706004934701172e-07 5.090535938645638e-05 +3 1500 4 25 1 3.1582065481685042 3.0957676796645961 5.7633236555203613 0.32048491920130329 1.1268009801165322e-06 0.00094825566560367022 -1.8223415071602311 1.1268015448264658e-06 6.2547962521591221e-05 +3 1500 4 25 3 3.1718079687688916 3.1718075251234743 5.4981265041926832 2.2458964208382781e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704361416239224 7.8605668043621887e-12 4.3633454367816762e-10 +3 1500 4 25 5 3.3170442487608387 3.3170439012574113 5.4981260003794903 1.6347592253218579e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731249183643071 6.1738007589111003e-12 3.4270334492984183e-10 +4 100 0.5 25 1 4.4459218792567778 4.1862871534264974 22.077052822713853 2.6128578273891452 2.1935502245210645e-06 0.0147677999213184 -2.3451254103878862 2.1935528367183268e-06 0.00012176257766962679 +4 100 0.5 25 3 4.6904578863907487 4.4215447254263003 20.274767131042225 2.4274578574618211 1.8517006890389585e-06 0.012466341086794733 -3.0034590600146451 1.8517008604983952e-06 0.00010278661451559229 +4 100 0.5 25 5 4.9038252494095973 4.6150013960632057 19.079594928209161 2.2912543716449512 1.6479515739015907e-06 0.011094625895203313 -3.5109376483101289 1.6479523605428227e-06 9.1476678353750914e-05 +4 100 1 25 1 4.5263251555693831 4.2138943451592796 16.584674486805739 1.965470692378005 2.5260247220205983e-06 0.0085030712481746276 -3.1531216166338347 2.526026621842223e-06 0.00014021796402121693 +4 100 1 25 3 4.7108904301553487 4.4296829714116281 14.417301773157259 1.6254417806013213 1.9120370115474528e-06 0.0064362738799047699 -3.8427902900623061 1.9120392654533863e-06 0.00010613595700546137 +4 100 1 25 5 4.8471550029477779 4.5912721624060842 12.975866302829616 1.361702473615606 1.5163577298128434e-06 0.0051043434776858049 -4.3459283627659282 1.5163598208346359e-06 8.4172068877859342e-05 +4 100 2 25 1 4.3019124900263037 4.1326608527224549 10.289337309154309 0.76349018989235828 1.5466510543683298e-06 0.0026031582345002633 -3.8958818915634272 1.5466535886529029e-06 8.5853654657391224e-05 +4 100 2 25 3 4.2082402658540339 4.1924642128617453 7.9259940832074829 0.077822593434828446 1.4603391025128065e-07 0.0002457887155045137 -4.3808058412549089 1.4603409191844789e-07 8.1062498983318285e-06 +4 100 2 25 5 4.3192648651884973 4.3192647263053008 7.6943145242868169 6.2757494556642257e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.696032723178809 3.1036885691353279e-12 1.7228357308550252e-10 +4 100 4 25 1 4.0051745686255105 4.0050287756412137 7.6955435231948179 0.00041923477874528103 1.5621620535007706e-09 1.3146323476484488e-06 -4.0098149350111498 1.5626505833126274e-09 8.6741636597980988e-08 +4 100 4 25 3 4.1729334888883667 4.1729333291926638 7.6943138716118415 4.0525182920525538e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313706135203 4.0159515435019528e-12 2.2292265020826827e-10 +4 100 4 25 5 4.3192648651884973 4.3192647263053008 7.6943136030941908 3.1378565412687465e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330369681005 3.1036885691353279e-12 1.7228357308550252e-10 +4 500 0.5 25 1 5.8702825782132528 4.4693976428357729 15.293555103261836 9.1684903725434612 5.5837864939537767e-06 0.037592137542268284 2.2238993753736978 5.5837871561608746e-06 0.00030995210414437271 +4 500 0.5 25 3 5.8702825782601371 4.7098874141239913 12.614251312245898 7.2392855674798611 3.9775195081876335e-06 0.026778147873445998 0.29469457027493995 3.9775201703947493e-06 0.00022078935167331389 +4 500 0.5 25 5 5.8702825785273234 4.8735460119823859 11.070049105475295 5.9096762924589576 3.0736699021056409e-06 0.020693094523689365 -1.0349147049463188 3.0736705643127693e-06 0.00017061729471622367 +4 500 1 25 1 5.8702825782132528 4.4693976428357729 10.583226987147309 5.4582397687504702 5.5837864939537767e-06 0.018796068771134142 -1.4863512284192932 5.5837871561608746e-06 0.00030995210414437271 +4 500 1 25 3 5.8702825782601371 4.7098874141239913 9.1764004492751692 4.0740321162941466 3.9775195081876335e-06 0.013389073936722999 -2.8705588809107745 3.9775201703947493e-06 0.00022078935167331389 +4 500 1 25 5 5.8702825785273234 4.8735460119823859 8.3690938744740606 3.2307074547159602 3.0736699021056409e-06 0.010346547261844682 -3.7138835426893162 3.0736705643127693e-06 0.00017061729471622367 +4 500 2 25 1 4.6954196518193392 4.2666338482001569 7.0043222484056828 1.7324278225543366 3.1600890129456843e-06 0.0053187250689607207 -3.7075836555545849 3.1600896371155281e-06 0.0001754143567646699 +4 500 2 25 3 4.3818724059597676 4.2831122886640625 5.9062436434897769 0.46596584142013375 8.2258435895327966e-07 0.0013844863335737284 -4.3608396169888497 8.2258679147114653e-07 4.5661215180191315e-05 +4 500 2 25 5 4.3192648651884973 4.3192647263053008 5.5130819206044173 6.6995179914819403e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326808019559 3.1036885691353279e-12 1.7228357308550252e-10 +4 500 4 25 1 4.0051745686255105 4.0050287756412137 5.5134563870320381 0.00044755306804655781 1.5621620535007706e-09 1.3146323476484488e-06 -4.0097866167218488 1.5626505833126274e-09 8.6741636597980988e-08 +4 500 4 25 3 4.1729334888883667 4.1729333291926638 5.5130817217279944 4.3261384385928636e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313432515055 4.0159515435019528e-12 2.2292265020826827e-10 +4 500 4 25 5 4.3192648651884973 4.3192647263053008 5.5130816399126639 3.349759081228143e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330157778465 3.1036885691353279e-12 1.7228357308550252e-10 +4 900 0.5 25 1 5.8702825782132528 4.4693976428357729 14.486823345796418 9.4678661986674211 5.5837864939537767e-06 0.037592137542268284 2.5232752014976576 5.5837871561608746e-06 0.00030995210414437271 +4 900 0.5 25 3 5.8702825782601371 4.7098874141239913 12.218462568804931 7.3439103404167465 3.9775195081876335e-06 0.026778147873445998 0.39931934321182538 3.9775201703947493e-06 0.00022078935167331389 +4 900 0.5 25 5 5.8702825785273234 4.8735460119823859 10.834645644512275 5.9577634211330359 3.0736699021056409e-06 0.020693094523689365 -0.98682757627224049 3.0736705643127693e-06 0.00017061729471622367 +4 900 1 25 1 5.8702825782132528 4.4693976428357729 10.386574091776176 5.4947284290212259 5.5837864939537767e-06 0.018796068771134142 -1.4498625681485375 5.5837871561608746e-06 0.00030995210414437271 +4 900 1 25 3 5.8702825782601371 4.7098874141239913 9.0647650148848662 4.0887872504008556 3.9775195081876335e-06 0.013389073936722999 -2.8558037468040656 3.9775201703947493e-06 0.00022078935167331389 +4 900 1 25 5 5.8702825785273234 4.8735460119823859 8.291443091616145 3.2386385257402321 3.0736699021056409e-06 0.010346547261844682 -3.7059524716650443 3.0736705643127693e-06 0.00017061729471622367 +4 900 2 25 1 4.7001590005524445 4.2680103979609116 6.9739042600974877 1.7430952307144043 3.1766187767125022e-06 0.0053465462058244007 -3.7055833611199773 3.1766199448097514e-06 0.00017633194253731621 +4 900 2 25 3 4.3835181336482059 4.2839279197297548 5.8915646430398301 0.46961108249062655 8.2866264017170841e-07 0.0013947166487832722 -4.3605988835199989 8.2866496927857779e-07 4.5998610562230239e-05 +4 900 2 25 5 4.3192648651884973 4.3192647263053008 5.5010162870367925 6.7018617921910106e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326805675754 3.1036885691353279e-12 1.7228357308550252e-10 +4 900 4 25 1 4.0051745686255105 4.0050287756412137 5.5013859410781105 0.0004477097136326158 1.5621620535007706e-09 1.3146323476484488e-06 -4.0097864600762634 1.5626505833126274e-09 8.6741636597980988e-08 +4 900 4 25 3 4.1729334888883667 4.1729333291926638 5.5010160907160035 4.3276518746360182e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313431001625 4.0159515435019528e-12 2.2292265020826827e-10 +4 900 4 25 5 4.3192648651884973 4.3192647263053008 5.5010160099520302 3.3509309349533112e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330156606611 3.1036885691353279e-12 1.7228357308550252e-10 +4 1500 0.5 25 1 5.8702825782132528 4.4693976428357729 14.385044944532346 9.5056358688529059 5.5837864939537767e-06 0.037592137542268284 2.5610448716831424 5.5837871561608746e-06 0.00030995210414437271 +4 1500 0.5 25 3 5.8702825782601371 4.7098874141239913 12.162463604700029 7.3587133862367029 3.9775195081876335e-06 0.026778147873445998 0.41412238903178178 3.9775201703947493e-06 0.00022078935167331389 +4 1500 0.5 25 5 5.8702825785273234 4.8735460119823859 10.797334794126009 5.9653851080829785 3.0736699021056409e-06 0.020693094523689365 -0.97920588932229791 3.0736705643127693e-06 0.00017061729471622367 +4 1500 1 25 1 5.8702825782132528 4.4693976428357729 10.354161202906722 5.5007425943546071 5.5837864939537767e-06 0.018796068771134142 -1.4438484028151564 5.5837871561608746e-06 0.00030995210414437271 +4 1500 1 25 3 5.8702825782601371 4.7098874141239913 9.0441361360843437 4.0915138208214525 3.9775195081876335e-06 0.013389073936722999 -2.8530771763834686 3.9775201703947493e-06 0.00022078935167331389 +4 1500 1 25 5 5.8702825785273234 4.8735460119823859 8.2761538990492678 3.2402001284409052 3.0736699021056409e-06 0.010346547261844682 -3.7043908689643712 3.0736705643127693e-06 0.00017061729471622367 +4 1500 2 25 1 4.701141534177224 4.2682950946359952 6.9671648654462732 1.7453271594699959 3.1800373192350715e-06 0.0053522999322984377 -3.7051458239431421 3.1800386027255236e-06 0.00017652170983766438 +4 1500 2 25 3 4.3838977053640029 4.2841159201584436 5.8881099031062636 0.47045269069827733 8.3006364395282359e-07 0.001397074669048461 -4.3605422458378733 8.300659463918794e-07 4.6076377818033828e-05 +4 1500 2 25 5 4.3192648651884973 4.3192647263053008 5.4981252052449037 6.7024234362556001e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326805114114 3.1036885691353279e-12 1.7228357308550252e-10 +4 1500 4 25 1 4.0051745686255105 4.0050287756412137 5.4984937713646289 0.00044774724709606417 1.5621620535007706e-09 1.3146323476484488e-06 -4.009786422542799 1.5626505833126274e-09 8.6741636597980988e-08 +4 1500 4 25 3 4.1729334888883667 4.1729333291926638 5.4981250095018712 4.3280145556323646e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313430638938 4.0159515435019528e-12 2.2292265020826827e-10 +4 1500 4 25 5 4.3192648651884973 4.3192647263053008 5.4981249289755798 3.351211759206052e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330156325787 3.1036885691353279e-12 1.7228357308550252e-10 +6 100 0.5 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 0.5 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 0.5 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 1 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 1 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 1 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 2 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 2 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 2 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 4 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 4 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 100 4 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 0.5 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 0.5 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 0.5 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 1 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 1 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 1 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 2 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 2 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 2 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 4 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 4 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 500 4 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 0.5 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 0.5 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 0.5 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 1 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 1 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 1 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 2 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 2 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 2 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 4 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 4 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 900 4 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 0.5 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 0.5 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 0.5 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 1 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 1 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 1 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 2 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 2 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 2 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 4 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 4 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +6 1500 4 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 +0.5 100 0.5 35 1 1.2271810577249567 1.0156742633135694 36.727526890478501 1.3937677093996341 6.4084874819047357e-06 0.043144332814037144 1.324198354893676 6.4084875654205928e-06 0.00035573064476384085 +0.5 100 0.5 35 3 1.3820725081190748 1.23590594075546 35.437272533569157 1.3188622296507599 4.3492676056184731e-06 0.029280895001193245 1.208076871496538 4.3492676238207038e-06 0.00024142479177467134 +0.5 100 0.5 35 5 1.5040185138680893 1.3907663555781669 34.321523320924868 1.2508842865693985 3.3145648367263044e-06 0.022314889254791897 1.0970581492150262 3.3145649539273518e-06 0.00018398917312946721 +0.5 100 1 35 1 1.3504861822474639 1.1011850264194769 34.839638048069958 1.2828345196212574 7.4810351834241664e-06 0.025182562395459452 1.181602117011151 7.4810354574219683e-06 0.00041526702511362579 +0.5 100 1 35 3 1.4975717374380502 1.3260225260646772 33.029360128404889 1.168155708412101 5.0431201297291511e-06 0.016976084755769449 1.0168633948284842 5.0431203539465276e-06 0.00027994006960569123 +0.5 100 1 35 5 1.6064561941983186 1.4749490741237072 31.546024349092519 1.0674427626544678 3.7997482905717835e-06 0.012790662798429315 0.86917986380342982 3.7997486375209519e-06 0.00021092137871334731 +0.5 100 2 35 1 1.4644152114378672 1.1794927780145676 32.124132557613137 1.1074588974675583 8.4631188194368302e-06 0.014244219717270863 0.96872933716878451 8.4631190387326913e-06 0.00046978179510034364 +0.5 100 2 35 3 1.5824429939934086 1.3917968196664439 29.801575499104395 0.94034020647078043 5.549490857078133e-06 0.0093403116243223078 0.75321804896464795 5.5494908623422954e-06 0.00030804834095710771 +0.5 100 2 35 5 1.6567817690446913 1.516112369582264 28.045578629532145 0.8018307996218148 4.0369688085848483e-06 0.0067945956955237762 0.57871443157383218 4.0369688249010042e-06 0.00022408930474054976 +0.5 100 4 35 1 1.5301446081095804 1.2243231693855137 28.651356039925037 0.85089148757819189 9.0252953516154122e-06 0.0075952076737017911 0.68648607969097408 9.0252955361138282e-06 0.00050098781771378454 +0.5 100 4 35 3 1.5808681646204101 1.3905800762562945 26.139769421686708 0.63790900482571766 5.5401240953393023e-06 0.004662273244570303 0.4515016191641506 5.5401241117661782e-06 0.00030752839920989057 +0.5 100 4 35 5 1.5929482323912298 1.4638777823902784 24.477209125600936 0.48176899447494614 3.7359431161039803e-06 0.0031439706645021341 0.28982905713192786 3.7359432001525863e-06 0.00020737958368873642 +0.5 500 0.5 35 1 2.1322280890259764 1.6191407399565589 31.20834819022889 8.1649378045074759 1.3974093007621385e-05 0.09407881675629505 7.5920860475746998 1.3974093041589783e-05 0.00077569209223368209 +0.5 500 0.5 35 3 2.3586780268021639 1.9676852789002786 28.704668773625173 7.4919803927468287 9.9801918441674942e-06 0.067190381457173654 6.6698264408576886 9.9801923954694454e-06 0.00055399347185508996 +0.5 500 0.5 35 5 2.5183118070645913 2.1911652834232003 26.845043734201283 6.928085273713755 7.9243754559577252e-06 0.053349857198068534 5.8957836746897136 7.9243766524831649e-06 0.00043987658354055872 +0.5 500 1 35 1 2.370533810076215 1.7650817464352881 26.820898540931893 6.9203662884235264 1.5802089032152963e-05 0.053192784591163556 6.0835871372969388 1.5802090039305326e-05 0.00087716292197087575 +0.5 500 1 35 3 2.5391188324462459 2.0923937723314689 23.828848171637418 5.8781288860595904 1.0938792233206911e-05 0.036822018770083571 4.8163389194220345 1.0938792548350884e-05 0.00060720469321958836 +0.5 500 1 35 5 2.6219165092091381 2.2671413953383865 21.779637204001766 5.0625388660084294 8.3614688112269048e-06 0.028146266511746596 3.8786717699609925 8.3614688613046955e-06 0.00046413926512931978 +0.5 500 2 35 1 2.4655402281598224 1.821221940614032 21.684482751016997 5.0226726306849869 1.6505052270116795e-05 0.027779545105834687 4.0629986468720229 1.6505052801645335e-05 0.00091618389129310767 +0.5 500 2 35 3 2.4737137235507287 2.0476906649233899 18.79350362530559 3.7331673878800138 1.0595214666547155e-05 0.017832736238481792 2.7624480368062878 1.0595214812072657e-05 0.00058813293433653381 +0.5 500 2 35 5 2.4359741829155896 2.129804930910387 17.045667668763731 2.8875767823301062 7.5712937418055553e-06 0.012743194784715637 1.9672326886665812 7.5712947059717175e-06 0.00042027725262124439 +0.5 500 4 35 1 2.2939339640625489 1.7189408099269561 17.070673038461024 2.8999839344063054 1.5224235734604677e-05 0.012811905602293443 2.154919206080177 1.5224236433618196e-05 0.00084508667408371896 +0.5 500 4 35 3 2.1662577056208447 1.8302689664896767 15.013750972256476 1.8522741306856525 8.9235037903717219e-06 0.0075095453195121549 1.2455666809284818 8.9235046570355199e-06 0.00049533747749295142 +0.5 500 4 35 5 2.0612830239485964 1.8411440826323697 13.929976412456043 1.2798497990403139 5.9094735850825503e-06 0.0049730980951136865 0.77357214099893956 5.9094736563857939e-06 0.00032803073307720201 +0.5 900 0.5 35 1 2.31303768515198 1.7305192008502881 30.9651442926423 9.2285313629617907 1.5369247337840501e-05 0.10347151712746407 8.4612081501937659 1.5369248316603311e-05 0.00085313618188194895 +0.5 900 0.5 35 3 2.5242954913245472 2.0823141638722542 28.497680197753063 8.3028476730406133 1.0861326278978993e-05 0.073122507784448121 7.2621150584721326 1.0861327325091763e-05 0.00060290465307198237 +0.5 900 0.5 35 5 2.661956830939185 2.2961143297518638 26.665911631845795 7.5574534895860754 8.5281215642451377e-06 0.05741450164103306 6.3118669372181193 8.528122736136889e-06 0.0004733901046981343 +0.5 900 1 35 1 2.5061495033005463 1.8448348450668783 26.550214707035927 7.5088085918416372 1.6800681790111687e-05 0.056554234419747218 6.4935209397990956 1.6800682856893055e-05 0.00093259410807066648 +0.5 900 1 35 3 2.6278485760090287 2.1520708779862319 23.600571505623687 6.2110131560317878 1.1397378196750006e-05 0.038365704818532291 5.018111707409358 1.1397378502768371e-05 0.00063266047753363151 +0.5 900 1 35 5 2.6807281065987572 2.3096192342338573 21.584973734062139 5.2661384147647201 8.605798065185739e-06 0.028968724437955437 3.991022923530732 8.605798225001681e-06 0.0004777018165418641 +0.5 900 2 35 1 2.5179411049525813 1.8516470006879908 21.453994693601466 5.2032539935237594 1.6885964274060162e-05 0.02842065559865373 4.1714734046716542 1.6885965475435848e-05 0.00093732808634115164 +0.5 900 2 35 3 2.4979443999609372 2.0643204240499156 18.630810656814695 3.8071890550247249 1.0723032337065257e-05 0.018047865320496823 2.8032865267470051 1.0723033034747442e-05 0.00059522803412419886 +0.5 900 2 35 5 2.4499316449211568 2.1402648257260828 16.921145145944244 2.9263225643677173 7.6314868422228315e-06 0.012844505396807987 1.987533739816683 7.6314879642873209e-06 0.00042361853812308191 +0.5 900 4 35 1 2.3066222912467951 1.7266361492868627 16.93815147517811 2.9352094974116789 1.5320615174131795e-05 0.012893013403220138 2.1754065883297229 1.5320616188729367e-05 0.0008504366466127875 +0.5 900 4 35 3 2.1720997625103111 1.8345021675013 14.923832765817018 1.8657223568802679 8.9560616294857524e-06 0.0075369442621333249 1.2530760040699729 8.9560625167381838e-06 0.00049714474142315761 +0.5 900 4 35 5 2.0648694667966918 1.8439711943208819 13.858942060751211 1.2868728690799189 5.9257551194311148e-06 0.0049867997668935158 0.77735837026339527 5.9257551301369353e-06 0.00032893450625239717 +0.5 1500 0.5 35 1 2.3661557920849847 1.7624652588214218 30.937684571541432 9.4975372904073438 1.5769323450393948e-05 0.1061649790402307 8.6661771916471988 1.5769324326685501e-05 0.00087534412027119081 +0.5 1500 0.5 35 3 2.5637458005334142 2.1090711579921742 28.465726959265041 8.483542743278937 1.1066957769062396e-05 0.074506895827688505 7.3862308056389114 1.1066958328000737e-05 0.00061431908565088742 +0.5 1500 0.5 35 5 2.6919732123077096 2.3176852868015683 26.631857954200381 7.6869817493142154 8.6521895764849537e-06 0.058249773868179498 6.3939964070138195 8.6521896667616304e-06 0.00048027697289823091 +0.5 1500 1 35 1 2.5336562255925146 1.8606944513471531 26.497584570708668 7.6272757881487294 1.6999228360412815e-05 0.057222579277433627 6.573274116116222 1.699922896667125e-05 0.00094361526320684149 +0.5 1500 1 35 3 2.6437448021733156 2.1626400624546891 23.55251223004224 6.2735988304708687 1.1478586089226946e-05 0.038639065759787511 5.0562997441809436 1.147858726950372e-05 0.00063716831915091427 +0.5 1500 1 35 5 2.6911583033955826 2.3171013698012195 21.54285303545079 5.304577165673301 8.6488312810601897e-06 0.029113582284131162 4.0128913368871277 8.6488313436142437e-06 0.00048009055473850922 +0.5 1500 2 35 1 2.5271309637052628 1.8569421198667895 21.405829174286549 5.2372467948208978 1.6952253679847026e-05 0.028532226862286098 4.1925051039950354 1.6952254612888007e-05 0.00094100774981337816 +0.5 1500 2 35 3 2.5025487176394452 2.0674713710193773 18.595034766038005 3.8221757612071356 1.0747249885561684e-05 0.018088625717361924 2.8118936765450364 1.0747250810459775e-05 0.00059657234584844718 +0.5 1500 2 35 5 2.4527867140560082 2.1424015619594936 16.892591831267747 2.9346638285288056 7.6437828876419026e-06 0.012865200790118611 1.9920751481784387 7.6437839519565224e-06 0.00042430107976444757 +0.5 1500 4 35 1 2.3092059348136673 1.7282005873639155 16.908013827891114 2.9428040046789152 1.5340208584356176e-05 0.01290950217327059 2.1799780105657098 1.5340209601359769e-05 0.00085152426318955152 +0.5 1500 4 35 3 2.1734109211700594 1.8354517435605917 14.902149712099357 1.8688583426506633 8.9633648486767835e-06 0.0075430902622675503 1.2548739757964207 8.9633657265315182e-06 0.00049755013747052556 +0.5 1500 4 35 5 2.065717304312797 1.8446393646778718 13.841264167049122 1.2885793408781767 5.9296031367500505e-06 0.0049900380532354799 0.77829766397249112 5.9296031403874277e-06 0.00032914810659935762 +1 100 0.5 35 1 1.5244849086572223 1.3686395881729871 35.614681637381977 1.329391172571714 4.5613446828893574e-06 0.030708677146331142 1.1673202265615941 4.5613447663767364e-06 0.00025319704503895291 +1 100 0.5 35 3 1.6900668219961628 1.5796807955307324 34.084826622622529 1.2360605194219443 3.1442240455745994e-06 0.021168091386182933 0.9953521295616895 3.1442245492655329e-06 0.00017453369687846421 +1 100 0.5 35 5 1.820652563933856 1.7339857985324918 32.798962899626147 1.1529284168568728 2.4090650297987754e-06 0.016218726136202778 0.83382386888325111 2.4090656100658491e-06 0.0001337255403866694 +1 100 1 35 1 1.6287652730833528 1.4400649465923978 33.417859734285784 1.1934994423628837 5.4566526794339695e-06 0.018368112594185321 0.98447395552651829 5.4566530696348407e-06 0.00030289498027392952 +1 100 1 35 3 1.7797977792253832 1.6489712320304548 31.367539915208681 1.0548837194009386 3.6774030732251403e-06 0.012378825934402204 0.76196054694275084 3.6774032452409448e-06 0.00020413007189791534 +1 100 1 35 5 1.8906710321428248 1.7909979673803336 29.725816319890615 0.93459230730218046 2.7374493996308595e-06 0.0092147662215731271 0.56695703998746549 2.7374500414726956e-06 0.00015195392958494008 +1 100 2 35 1 1.7143809740641234 1.498174670997346 30.408273642115645 0.98566882960810798 6.184939589920448e-06 0.010409831214296542 0.73151205385258922 6.1849396751704356e-06 0.00034332165834973275 +1 100 2 35 3 1.8229412536263563 1.6821010847418338 27.904878077878617 0.7902344319318475 3.9323024865736111e-06 0.006618432496171946 0.46961729431334293 3.9323030852078006e-06 0.00021827938302568974 +1 100 2 35 5 1.8867415832145316 1.7878064605386046 26.053058264913105 0.63008305602031633 2.7190677811975694e-06 0.0045764451294927778 0.26529641664105624 2.7190683724044218e-06 0.00015093357604243252 +1 100 4 35 1 1.7317569907587536 1.5099049678235619 26.785243027062798 0.6951281753684353 6.3319419778384123e-06 0.0053286249841014762 0.43104542566061277 6.3319420996747149e-06 0.00035148165970994808 +1 100 4 35 3 1.753929593785607 1.6290478172146314 24.263378432042828 0.46071138036400594 3.5241034964342812e-06 0.0029656977280246169 0.18357512767235507 3.5241040445426882e-06 0.00019562054091272208 +1 100 4 35 5 1.7428549660544808 1.6703040660867954 22.652950121909697 0.29430419460823209 2.0422177191970018e-06 0.0017186216171239822 0.023742505474394493 2.0422181066044033e-06 0.00011336209306713313 +1 500 0.5 35 1 2.4097969192207502 1.9459116622059209 29.98624382563888 7.8478573497518749 1.1792213023547683e-05 0.07938958525526342 6.9615173464211084 1.1792213034384958e-05 0.00065457746513377507 +1 500 0.5 35 3 2.6414168449318529 2.2783372444722936 27.432377171733513 7.1126279825068508 8.5156574619660684e-06 0.057330588646200061 5.8989189581550914 8.5156585430382221e-06 0.00047269822609149169 +1 500 0.5 35 5 2.8024000113263088 2.4942225081869083 25.569988105652921 6.5056648492280136 6.783693621895166e-06 0.04567036077669237 5.0301556604829827 6.783694789581669e-06 0.00037655813430927945 +1 500 1 35 1 2.6235245692667446 2.072093709686234 25.450492767022148 6.4644971744328945 1.3370809126381943e-05 0.045008642099284291 5.2781848314816813 1.3370809229016999e-05 0.00074220423141920617 +1 500 1 35 3 2.7735866529515736 2.3669460965843721 22.484517495204837 5.3524137528952327 9.1959964794881571e-06 0.030955442589850161 3.9257457130423679 9.1959973382292122e-06 0.00051046335488366429 +1 500 1 35 5 2.8386872041976505 2.5201606088834128 20.470399591606117 4.4991218219293305 6.9327512721219984e-06 0.023336936293153955 2.9609111350556634 6.9327519044198005e-06 0.00038483219008713851 +1 500 2 35 1 2.6499446326008562 2.0872338061930247 20.32229217124123 4.4334118973015606 1.3560159378805962e-05 0.022823015216248198 3.2065231820442248 1.3560160720650209e-05 0.00075271499975854616 +1 500 2 35 3 2.6228944199193758 2.2657128752630316 17.556494566720275 3.1393154198927973 8.4187087056416487e-06 0.014169473346333148 1.9539616291148019 8.4187087858417894e-06 0.00046731661314692143 +1 500 2 35 5 2.5625013403586903 2.3180488412826472 15.900923026519516 2.3106904690149004 5.7708871765441079e-06 0.0097129423159564212 1.2151896191227294 5.7708876636245707e-06 0.00032033792193308745 +1 500 4 35 1 2.3997238866863233 1.939809908739246 15.95821855136486 2.3399654766590161 1.1715855870858875e-05 0.0098594400457381673 1.4665054185636028 1.1715856222931422e-05 0.00065033895214717857 +1 500 4 35 3 2.2435662571701993 1.9973232543602839 14.095170372269429 1.3679471816731938 6.3565256514074356e-06 0.0053493132938869075 0.67961758459901711 6.3565265764579694e-06 0.00035284632675314844 +1 500 4 35 5 2.1221400823632703 1.9771030292523122 13.132055043767412 0.85020657992840487 3.8090899379790755e-06 0.0032055271323149226 0.28715026847247505 3.8090902778134552e-06 0.00021143992660635334 +1 900 0.5 35 1 2.5816264198949348 2.0478704314977563 29.844675383735439 8.819745491487593 1.3067829847900243e-05 0.087977514461406503 7.6962231410517328 1.306783112686707e-05 0.00072538612971785013 +1 900 0.5 35 3 2.7919324596471053 2.3790333029610231 27.318746195609606 7.8285212645810009 9.2887819722608287e-06 0.06253555179437377 6.3708531683848051 9.2887834689446125e-06 0.00051561384784594021 +1 900 0.5 35 5 2.9281359985694984 2.5832282700897977 25.468353005184088 7.0453976520962147 7.295110913500471e-06 0.049113413119101668 5.3471247401526476 7.2951125574111324e-06 0.00040494657548771206 +1 900 1 35 1 2.7387763789772008 2.1373534777502803 25.253882879952233 6.9517441284433605 1.4186893996166424e-05 0.047755736271341317 5.582945863780548 1.4186894807976517e-05 0.00078750456885798043 +1 900 1 35 3 2.8435526699444686 2.4127538283257004 22.311779670402871 5.6118691820041811 9.5476089579507497e-06 0.032139035897568516 4.065151665393941 9.5476099290985351e-06 0.00052998112290305493 +1 900 1 35 5 2.8832405471440694 2.5517315400877472 20.321037059698348 4.6521576967875333 7.1141569775434476e-06 0.023947581796571714 3.0351835290913538 7.1141574122744926e-06 0.00039490188244654413 +1 900 2 35 1 2.6882593233023426 2.1090014714804441 20.141895738728294 4.5638715328477186 1.3832377861137991e-05 0.023281184356510543 3.2768029059161661 1.3832377864056055e-05 0.00076782558224013629 +1 900 2 35 3 2.6401513904613836 2.2774763139715883 17.429582623260302 3.1909444752466452 8.5090460988360481e-06 0.01432151961967522 1.9791845146603217 8.5090471186824225e-06 0.00047233123056799459 +1 900 2 35 5 2.5723331683213262 2.3254186564632047 15.803732015448793 2.33704750145789 5.8132683800295343e-06 0.009784273841273344 1.2271916528697113 5.8132693975698267e-06 0.00032269050222424796 +1 900 4 35 1 2.4086481778524038 1.9452164824375444 15.853840266883502 2.3636962402552455 1.1783513680756646e-05 0.0099163772535415008 1.4788308348395365 1.1783513709649752e-05 0.00065409457172632538 +1 900 4 35 3 2.2477166258411874 2.0003515007062775 14.023225567698727 1.3767698209659738 6.3798038985267273e-06 0.0053689030263291944 0.68387177149653289 6.3798047417975116e-06 0.00035413848136539063 +1 900 4 35 5 2.1246933315957759 1.9791332088024252 13.074489350197986 0.8546424967949604 3.8207775282655945e-06 0.0032153627855509535 0.28911735924925752 3.8207777752222473e-06 0.00021208869138064098 +1 1500 0.5 35 1 2.628023265641608 2.0746791194378891 29.835430056245649 9.0542917137547381 1.3403144575394788e-05 0.090234978526261472 7.8611236388362684 1.3403144891008829e-05 0.00074399916131050951 +1 1500 0.5 35 3 2.8252563482863162 2.400851263807473 27.300116678166717 7.9813738736793418 9.4562545067914442e-06 0.06366303948743729 6.4665240443840677 9.4562545055849864e-06 0.00052491004749292177 +1 1500 0.5 35 5 2.9531248049979708 2.6006179440836386 25.445381922302005 7.1531657529713879 7.3950089356792394e-06 0.049785963939948989 5.4088249451309842 7.395009324304127e-06 0.00041049177487116997 +1 1500 1 35 1 2.7608331386637599 2.1496059341173188 25.212245859604629 7.0466509794771088 1.4340086265433988e-05 0.048271410076469276 5.641330166087231 1.4340086358112645e-05 0.00079600812423606139 +1 1500 1 35 3 2.8560635343690097 2.4208610575069676 22.273182652690224 5.6607671285285424 9.6098308500978372e-06 0.032348486413832547 4.0920684168079635 9.6098323926076077e-06 0.00053343504816028909 +1 1500 1 35 5 2.8913837255258907 2.5574683133145744 20.287196867983802 4.6817489323148607 7.1471181133798931e-06 0.024058535139187404 3.0501708693157856 7.147118146797463e-06 0.00039673150967512978 +1 1500 2 35 1 2.6952046125827658 2.1129230890782806 20.102627089697044 4.5891083806303818 1.3881416807362281e-05 0.023363721484917388 3.2909630645987829 1.3881417043469038e-05 0.00077054771265440121 +1 1500 2 35 3 2.6436139914030057 2.279831486680675 17.400582816045734 3.2018354978777928 8.527132188579359e-06 0.014351960198571304 1.9847382968885081 8.527133363783409e-06 0.00047333518533352258 +1 1500 2 35 5 2.5744585341775612 2.3270102226588532 15.780641312527376 2.3429607268177546 5.8224207954185568e-06 0.009799678211521055 1.229987730597617 5.822421900737436e-06 0.00032319855124826179 +1 1500 4 35 1 2.4105653005771597 1.9463765640987614 15.829242082673908 2.3690191711891857 1.1798030696323002e-05 0.0099285940003329635 1.4816919978300263 1.1798030699528234e-05 0.00065490039964075683 +1 1500 4 35 3 2.2486909706599496 2.001062150417146 14.005374180186825 1.3788956271576454 6.3852666650837887e-06 0.0053735001995913875 0.68492231448939389 6.3852674822714148e-06 0.00035444171425320095 +1 1500 4 35 5 2.1253210906372084 1.9796322801957107 13.059814582620028 0.85575130332575622 3.8236506340000658e-06 0.0032177806382495812 0.28961808722163962 3.8236508589322552e-06 0.00021224817423992536 +2 100 0.5 35 1 2.2924943391158052 2.1966220972656689 32.773627682353691 1.1512448854286839 2.3971135591961348e-06 0.016138264369404687 0.40784100389142552 2.3971141979848893e-06 0.00013306212589424865 +2 100 0.5 35 3 2.462810656557223 2.391526826396138 30.903621010666562 1.0217765986008822 1.690163169871706e-06 0.011378810135289404 0.065774611988355547 1.6901638396636238e-06 9.3819807919157577e-05 +2 100 0.5 35 5 2.5989638549189449 2.5417000698386252 29.4200937087064 0.91119474062220229 1.2958973791276225e-06 0.0087244654804729069 -0.23807725761641718 1.295898219585954e-06 7.1934400199053793e-05 +2 100 1 35 1 2.3444210877261438 2.2303492403754781 29.889291523871272 0.94697068364512482 2.8185527666708916e-06 0.0094877753106752359 0.14219519738245701 2.8185527756899989e-06 0.00015645588541160138 +2 100 1 35 3 2.4859628857014897 2.4086518059840119 27.501397693924382 0.75654766911691729 1.8215708678803905e-06 0.0061317479350702676 -0.23086459267115722 1.8215709691982471e-06 0.00010111412540650831 +2 100 1 35 5 2.5879978182106971 2.5331001401933158 25.65845425425314 0.59404044215455531 1.2464971045978631e-06 0.0041959421848257678 -0.53890642677135348 1.246498356510385e-06 6.9192248487948097e-05 +2 100 2 35 1 2.3454631106408939 2.2310229681164695 26.235556132166508 0.64651518181285983 2.8269705106326343e-06 0.0047580555049298286 -0.15952275646447567 2.8269705349437733e-06 0.00015692314931688999 +2 100 2 35 3 2.4102985451762065 2.3524706132313176 23.480870517907576 0.38162282017772009 1.3904276606595132e-06 0.0023402196662911769 -0.50536156684734934 1.3904276660887935e-06 7.7181663396546957e-05 +2 100 2 35 5 2.4331707823156132 2.4103780679242095 21.503261436843538 0.16636520945232425 5.413380728209483e-07 0.00091112255601046585 -0.75030053686520726 5.4133892603921728e-07 3.0049343660239649e-05 +2 100 4 35 1 2.2161264987064557 2.1464933523469587 22.335896857274868 0.25982233187030657 1.7705822229075985e-06 0.0014900276569830768 -0.39878312061389509 1.770582508060372e-06 9.8283791732465837e-05 +2 100 4 35 3 2.1713893130714541 2.1713888619558692 20.110909942180726 1.9001844648869337e-06 1.1500376674256073e-11 9.6781042352410862e-09 -0.61192023598081968 1.2390583932180694e-11 6.8779261349878953e-10 +2 100 4 35 5 2.316213588222487 2.3162132275844125 20.110906404535228 1.4604310845101054e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106166587657754 9.7500543226876377e-12 5.4121866903622745e-10 +2 500 0.5 35 1 3.1038197819873519 2.6817446021487621 27.369527542991769 7.0931728868023107 8.4501064005549744e-06 0.05688927440195455 5.0593680557872514 8.450106451146477e-06 0.00046905947550077582 +2 500 0.5 35 3 3.3378657532356817 2.9859871030047254 24.893365373433589 6.2688956061200702 6.2440236684670063e-06 0.042037100955839908 3.7513064834790986 6.2440256700531488e-06 0.0003466014804359228 +2 500 0.5 35 5 3.4989182215773296 3.1893462566169077 23.139392160831711 5.6129959255411794 5.0091349025383782e-06 0.033723368260569833 2.7442083517117659 5.0091359293190987e-06 0.00027805361805823475 +2 500 1 35 1 3.2336340671200556 2.7494080434837453 22.563465333830706 5.3842768046978691 9.2926252860579779e-06 0.031280713209621461 3.0866741800666229 9.2926254210331778e-06 0.00051582711190858608 +2 500 1 35 3 3.3321840267398475 2.9825540295468045 19.762218611050276 4.1814491425735518 6.2177770079470279e-06 0.020930199313941834 1.6760169709101782 6.2177787548119283e-06 0.00034514453260127274 +2 500 1 35 5 3.3580124865607615 3.0971791039661021 17.875888838947098 3.2948319712548213 4.4816574997325834e-06 0.015086096623654332 0.73399387756285206 4.4816587456306562e-06 0.00024877372998227345 +2 500 2 35 1 3.0762367953147161 2.6669650074127587 17.465709268064231 3.094843563976021 8.2660119327993956e-06 0.013912470410549247 1.1154483238275048 8.2660134262488264e-06 0.00045884060095747022 +2 500 2 35 3 2.9706566767178093 2.7514029222184364 15.004900958757629 1.8476538921213286 4.4490468478199612e-06 0.0074881615377102757 0.070651355612424194 4.4490471186508204e-06 0.00024696348146826646 +2 500 2 35 5 2.8575434478737622 2.7404216516422988 13.541005540475773 1.0712493160457268 2.4367918971583349e-06 0.0041013484424526105 -0.50005971542679784 2.4367934603551339e-06 0.00013526469388593584 +2 500 4 35 1 2.641226578697887 2.4168582224597079 13.644724062360506 1.1270305639357985 5.1475353940568627e-06 0.0043318915118489131 -0.086385300118391628 5.1475364662297113e-06 0.0002857361346783076 +2 500 4 35 3 2.4187103358830759 2.3587465426147762 12.186215642092591 0.3324050949043249 1.4385958521894316e-06 0.0012106456165945911 -0.5654270621553209 1.4385960081587888e-06 7.9855454241398212e-05 +2 500 4 35 5 2.316213588222487 2.3162132275844125 11.587401674861916 2.0863013019400967e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106104000636011 9.7500543226876377e-12 5.4121866903622745e-10 +2 900 0.5 35 1 3.2494835350655213 2.7574503829524248 27.403444959739758 7.8632579467958248 9.392732675024652e-06 0.063235386775554445 5.532638656595263 9.3927332423517482e-06 0.00052138402677500686 +2 900 0.5 35 3 3.4558690619563572 3.0557696581028857 24.906082930183693 6.7986506636377406 6.7773824711865854e-06 0.04562787175141466 4.0248659696361546 6.7773830612428528e-06 0.00037620777470124081 +2 900 0.5 35 5 3.5929454186812491 3.2485000412285352 23.131342130497821 5.9949914487967639 5.3474811987387379e-06 0.036001241978960312 2.9164892234464626 5.3474817489337508e-06 0.00029683495692110746 +2 900 1 35 1 3.3070921393900439 2.7862708639920024 22.462444512268426 5.6828442871416947 9.7514213455261271e-06 0.032825106480214174 3.2308824001488641 9.7514213450557595e-06 0.0005412945514879689 +2 900 1 35 3 3.3723052911775762 3.0066545332161478 19.663141718020743 4.3264297325806425 6.4020198476009347e-06 0.021550395141356388 1.7347787914457897 6.4020199489026625e-06 0.0003553716319124431 +2 900 1 35 5 3.3824834473631458 3.1134770426458331 17.788961689911051 3.37664029839156 4.574958532376353e-06 0.015400165334535209 0.7629830489607845 4.5749587498320934e-06 0.00025395274770092109 +2 900 2 35 1 3.094384784122898 2.6767046766005889 17.360207927740404 3.1549686503299763 8.3873319910971003e-06 0.014116663404098593 1.1398435596314709 8.3873321902818479e-06 0.00046557492035980281 +2 900 2 35 3 2.9785562564171668 2.7567030095412397 14.931708060128731 1.8699689637254857 4.4896333390886336e-06 0.0075564723946790228 0.078158936340156249 4.4896341866966468e-06 0.00024921644111555074 +2 900 2 35 5 2.8618327447302203 2.7436464556489675 13.485379747461092 1.0816532182658802 2.4552959921420833e-06 0.004132492563224309 -0.4972335092962521 2.4552975499834674e-06 0.00013629184290776949 +2 900 4 35 1 2.6450693435230734 2.4191964291717651 13.584154214834033 1.1360242189980205 5.1767153463048e-06 0.0043564478048673033 -0.083320124327020739 5.1767165743296882e-06 0.00028735590198888082 +2 900 4 35 3 2.4204419387995419 2.3600375550150345 12.143273492557801 0.33521128859796745 1.4485042386818324e-06 0.0012189839867186908 -0.56486378198499199 1.4485044676912994e-06 8.0405465872400743e-05 +2 900 4 35 5 2.316213588222487 2.3162132275844125 11.548723908445817 2.0891413621271226e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106103716629992 9.7500543226876377e-12 5.4121866903622745e-10 +2 1500 0.5 35 1 3.2830267381512455 2.7743103247548113 27.415037768659786 8.0315317421650825 9.6025746456148642e-06 0.064648121347177054 5.6305072348060428 9.6025763046750063e-06 0.00053303226781432173 +2 1500 0.5 35 3 3.4794683558397903 3.0693699227736611 24.902715021719267 6.9044296881820379 6.881295162361521e-06 0.046327450824372625 4.0786541665306606 6.8812973396600016e-06 0.00038197598332833759 +2 1500 0.5 35 5 3.6108353377794318 3.2595323048783413 23.122111252233935 6.069032296286327 5.4105642295896714e-06 0.03642594051908165 2.9503484254670997 5.4105663573502263e-06 0.0003003367392367597 +2 1500 1 35 1 3.3205185401551809 2.7928942775669725 22.435954261268765 5.7395319074603552 9.8338400275725335e-06 0.033102543165418372 3.2590033142841475 9.8338408055384549e-06 0.00054586959786502662 +2 1500 1 35 3 3.3798749262966958 3.0111642406955914 19.638585760368009 4.3549774539075159 6.4364914316195183e-06 0.02166643293480798 1.7469651051432344 6.4364915057648378e-06 0.00035728512382818972 +2 1500 1 35 5 3.3874145192932277 3.1167467105588722 17.767731547262322 3.3936947269920075 4.5936745118205184e-06 0.015463166818766848 0.76935723871015371 4.5936751262934719e-06 0.00025499168061579082 +2 1500 2 35 1 3.0980624722030483 2.6786711288667853 17.335377208504145 3.1676524506514903 8.4118253985519831e-06 0.01415788809736542 1.1452545418779758 8.4118254381291164e-06 0.00046693452334882691 +2 1500 2 35 3 2.9803445993925757 2.7579014341079509 14.913712573878039 1.8751363669657937 4.4988103170188584e-06 0.0075719181059785562 0.079966394976573874 4.4988113004219672e-06 0.0002497258562543418 +2 1500 2 35 5 2.862871493512269 2.7444270338495826 13.471246554287468 1.0842039848379716 2.4597749546849042e-06 0.0041400310756718513 -0.49652055165085529 2.4597764966716861e-06 0.00013654046609334921 +2 1500 4 35 1 2.6459933495754995 2.4197583457381491 13.568864139850621 1.1382215397018878 5.183727796243237e-06 0.0043623491090915836 -0.082550706307162436 5.1837290535255198e-06 0.00028774515978493035 +2 1500 4 35 3 2.4208888302971436 2.3603706881758812 12.132018103629591 0.33593864890879255 1.451060989794133e-06 0.001221135612223602 -0.56471581816424965 1.4510612390191051e-06 8.0547390453461284e-05 +2 1500 4 35 5 2.316213588222487 2.3162132275844125 11.538435135929339 2.0898968546845254e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106103641080737 9.7500543226876377e-12 5.4121866903622745e-10 +3 100 0.5 35 1 3.2026404976412541 3.1213111813649936 30.022892950528764 0.95701927221937311 1.443302220643957e-06 0.0097168499641343952 -1.276504057638892 1.4433041375011859e-06 8.0116799195181012e-05 +3 100 0.5 35 3 3.3703996161574552 3.3069339042635022 28.154458420852521 0.81075184495051467 1.0298506618893426e-06 0.0069333395486487013 -1.7767846721024427 1.0298508669972792e-06 5.7166298473343278e-05 +3 100 0.5 35 5 3.5072991590756168 3.4548888617253568 26.75370627600055 0.69237429584363763 7.8648018243740592e-07 0.0052948785245405128 -2.1949900824014601 7.8648046272517452e-07 4.3656978225099892e-05 +3 100 1 35 1 3.2059651727892433 3.1232075437376485 26.412262691971449 0.6622856668346575 1.4667950579212767e-06 0.0049375062624083628 -1.5780800477271213 1.4667969675380942e-06 8.1420869694037981e-05 +3 100 1 35 3 3.328343256921011 3.2789364127763529 23.997797861562312 0.43423068651350016 8.1660490282607972e-07 0.0027488447004527191 -2.0629937232892348 8.1660637664520701e-07 4.532924655260655e-05 +3 100 1 35 5 3.4146890933943501 3.3886377087302106 22.174590234032323 0.24204943007484303 4.0863519248584435e-07 0.0013755424188561659 -2.4415757234092839 4.0863725204648508e-07 2.2683166919038863e-05 +3 100 2 35 1 3.1017191740492418 3.0627709956460372 21.935665717620964 0.21543434272506357 7.1778469578041825e-07 0.0012080987085882678 -1.8142055286591998 7.1778469911213076e-07 3.9843724624597879e-05 +3 100 2 35 3 3.1718079687688916 3.1718075251234743 20.110915486303384 2.5893564141732384e-06 7.8357082936797437e-12 1.318822918086397e-08 -2.1704357981639291 7.8605668043621887e-12 4.3633454367816762e-10 +3 100 2 35 5 3.3170442487608387 3.3170439012574113 20.110909818095763 1.8847598637350416e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731246683636687 6.1738007589111003e-12 3.4270334492984183e-10 +3 100 4 35 1 3.0049013820550252 3.004900886809561 20.110907220723696 1.5618888666857345e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415925730379614 1.1003398397039095e-11 6.1079091851452102e-10 +3 100 4 35 3 3.1718079687688916 3.1718075251234743 20.11090507112322 1.294678884988798e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704370928414582 7.8605668043621887e-12 4.3633454367816762e-10 +3 100 4 35 5 3.3170442487608387 3.3170439012574113 20.11090223701833 9.4238029157978076e-07 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731256107432409 6.1738007589111003e-12 3.4270334492984183e-10 +3 500 0.5 35 1 4.0081079200039822 3.512878223112867 24.939602099050944 6.2853599130887066 6.2796426926771853e-06 0.042276901538953228 2.2685508954746876 6.2796434923385461e-06 0.00034857860074041336 +3 500 0.5 35 3 4.2554192041169667 3.8019069525693912 22.789429895289942 5.4747968746609157 4.7864550219612698e-06 0.032224204080919562 0.91448610389517437 4.786456409863963e-06 0.00026569283429719474 +3 500 0.5 35 5 4.4373459837746827 4.007177599031758 21.323490262467402 4.8698650858368016 3.9233986596716479e-06 0.026413786094298425 -0.070714909376484059 3.9234010880310727e-06 0.00021778523941332628 +3 500 1 35 1 4.005342063906502 3.5117839174579415 19.811342558105192 4.2037655650127075 6.2661714455661355e-06 0.021093104034352269 0.19315591004952015 6.2661719507505461e-06 0.00034783080492648049 +3 500 1 35 3 4.0563291841209193 3.7078010730638336 17.395625493237812 3.0604325893505666 4.0743801547396488e-06 0.013715124973197901 -1.0641201092374657 4.0743806824211367e-06 0.0002261660106811622 +3 500 1 35 5 4.0538384594088281 3.8070293711011152 15.773873176745258 2.2456288246241427 2.7894925876035822e-06 0.0093899533175094731 -1.8733754595846102 2.7894933727162627e-06 0.00015484281835782753 +3 500 2 35 1 3.6007903986991447 3.3326425866971379 14.729689145317172 1.7035237244212404 4.0573158869822435e-06 0.0068288417295781969 -1.3925893089133812 4.057317231336896e-06 0.00022521883049330535 +3 500 2 35 3 3.4133890379016747 3.3351900232707523 12.611851450036237 0.56653549629715583 1.2449894481437017e-06 0.0020954335657339582 -2.1142556753011492 1.2449915386577742e-06 6.9108606087026043e-05 +3 500 2 35 5 3.3170442487608387 3.3170439012574113 11.587402761205848 2.6924772527081586e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731238606462798 6.1738007589111003e-12 3.4270334492984183e-10 +3 500 4 35 1 3.0049013820550252 3.004900886809561 11.587401934608707 2.2312390646206381e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415919036877635 1.1003398397039095e-11 6.1079091851452102e-10 +3 500 4 35 3 3.1718079687688916 3.1718075251234743 11.587401250512038 1.8495156139941571e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704365380047292 7.8605668043621887e-12 4.3633454367816762e-10 +3 500 4 35 5 3.3170442487608387 3.3170439012574113 11.587400348576278 1.3462387382645602e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731252068847942 6.1738007589111003e-12 3.4270334492984183e-10 +3 900 0.5 35 1 4.1352539931201298 3.5612471952722555 25.01486135780285 6.8466929961893381 6.8748197751133297e-06 0.046283856097329067 2.5474244258797683 6.8748197768907267e-06 0.0003816164183675119 +3 900 0.5 35 3 4.3576166816863715 3.8460317541740077 22.814474386061256 5.8477292925026134 5.1199493957280896e-06 0.034469412844146799 1.0713012654433935 5.1199508148469167e-06 0.00028420487454048943 +3 900 0.5 35 5 4.5221982016091875 4.0456871062853477 21.323109820520294 5.1402408638018624 4.1411420974965e-06 0.027879716296411547 0.029776533549803474 4.1411443596699765e-06 0.00022987201552428403 +3 900 1 35 1 4.0500683199422403 3.5292597014345466 19.738236553500087 4.3638165485302505 6.4812752860908515e-06 0.021817183757639604 0.253214404376358 6.4812764898197194e-06 0.00035977110684539104 +3 900 1 35 3 4.08092179039995 3.7200026717187669 17.329429054784796 3.1389942563657356 4.1667676844558398e-06 0.014026118662519847 -1.040234465219084 4.1667689450392532e-06 0.00023129441826473789 +3 900 1 35 5 4.0694035092156984 3.8159602302253628 15.718462823444753 2.2916514902108349 2.8401653105775554e-06 0.0095605271721636159 -1.8619936561590369 2.8401654242919099e-06 0.00015765558835925116 +3 900 2 35 1 3.6087376662146498 3.3365197300563576 14.668555065719456 1.7277952570102451 4.1051925673075144e-06 0.0069094226558816842 -1.3861732393557822 4.1051945776187349e-06 0.00022787646836629116 +3 900 2 35 3 3.4165827247198108 3.3372742550103514 12.570938877140167 0.57461260201890729 1.2608558091990144e-06 0.0021221381338497186 -2.1131418651997973 1.2608578031801603e-06 6.9989331289489884e-05 +3 900 2 35 5 3.3170442487608387 3.3170439012574113 11.548724980631881 2.6961424923754862e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731238569810401 6.1738007589111003e-12 3.4270334492984183e-10 +3 900 4 35 1 3.0049013820550252 3.004900886809561 11.548724164807428 2.2342764212091026e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415919006504069 1.1003398397039095e-11 6.1079091851452102e-10 +3 900 4 35 3 3.1718079687688916 3.1718075251234743 11.548723489626312 1.8520333409099976e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704365354870023 7.8605668043621887e-12 4.3633454367816762e-10 +3 900 4 35 5 3.3170442487608387 3.3170439012574113 11.548722599445098 1.3480713616509377e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731252050521708 6.1738007589111003e-12 3.4270334492984183e-10 +3 1500 0.5 35 1 4.1614539446448511 3.5707439302946486 25.022370674081827 6.9595163466393331 6.9916102319199545e-06 0.04707013310141097 2.602774761446045 6.9916126073954083e-06 0.00038809950637776344 +3 1500 0.5 35 3 4.3773703484331756 3.8542315596011436 22.810433487968098 5.919870887336673 5.1818941606426518e-06 0.034886448152572934 1.1023876892997144 5.1818967654624032e-06 0.00028764345076116588 +3 1500 0.5 35 5 4.5384693764326167 4.0528282862443525 21.315088468325957 5.1925723577931482 4.1815061457121331e-06 0.028151462154518383 0.05013708489653812 4.1815067056849733e-06 0.00023211250100943511 +3 1500 1 35 1 4.058600069204422 3.5325399980931871 19.718296206088823 4.3953184176602864 6.5216446456861437e-06 0.021953074565789491 0.26570872131299339 6.5216449669416501e-06 0.0003620119326639828 +3 1500 1 35 3 4.0860206246134068 3.722512288839078 17.312515719060624 3.1556599051006766 4.185767236462917e-06 0.014090074704988959 -1.0348796208519757 4.1857690580459456e-06 0.0002323491011960003 +3 1500 1 35 5 4.0728492842306618 3.8179284309058636 15.704316723551671 2.3020013891502482 2.8513313419735888e-06 0.0095981141204195593 -1.859301909462157 2.8513317176588632e-06 0.00015827542146316199 +3 1500 2 35 1 3.6105667393157512 3.3374100818585246 14.653240435813904 1.7334698202175827 4.1161866460039655e-06 0.0069279267175500082 -1.3846102096797361 4.1161887603852674e-06 0.00022848674773162737 +3 1500 2 35 3 3.4173933471552638 3.3378029435277474 12.560267357216281 0.57667102452251617 1.264880433178602e-06 0.0021289119520446114 -2.1128516179864776 1.2648823919259202e-06 7.021273338473052e-05 +3 1500 2 35 5 3.3170442487608387 3.3170439012574113 11.538436204671257 2.6971174920120689e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731238560060405 6.1738007589111003e-12 3.4270334492984183e-10 +3 1500 4 35 1 3.0049013820550252 3.004900886809561 11.538435391467448 2.2350844006702175e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415918998424274 1.1003398397039095e-11 6.1079091851452102e-10 +3 1500 4 35 3 3.1718079687688916 3.1718075251234743 11.538434718455193 1.8527030896109409e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704365348172536 7.8605668043621887e-12 4.3633454367816762e-10 +3 1500 4 35 5 3.3170442487608387 3.3170439012574113 11.538433831133471 1.3485588605810506e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731252045646719 6.1738007589111003e-12 3.4270334492984183e-10 +4 100 0.5 35 1 4.1962194595268851 4.0898493094703312 28.151157577577848 0.810482062845018 1.0292211734426347e-06 0.0069291015971626379 -3.6220642357202215 1.0292215164921699e-06 5.7131363668729942e-05 +4 100 0.5 35 3 4.3690428176794081 4.2767255634586814 26.680921523169829 0.68600236413580351 7.7498386883723989e-07 0.0052174810447918772 -4.1142032423318673 7.7498632865195009e-07 4.3018946913791288e-05 +4 100 0.5 35 5 4.5148087930556438 4.4306594664553103 25.654409958405438 0.59366736095218409 6.226815319115559e-07 0.0041921247916617242 -4.5022116085645862 6.2268414025876682e-07 3.4564759381557971e-05 +4 100 1 35 1 4.1530533130750058 4.0715203665770359 23.959477722285961 0.43037953600340551 8.0742897857732545e-07 0.0027179568247423817 -3.9079653344208305 8.0743061850017962e-07 4.4819906661125706e-05 +4 100 1 35 3 4.2640128524057399 4.2225667026265805 21.993798695787667 0.22194228045536013 3.7092761481740551e-07 0.0012486116660746422 -4.3567670926580107 3.7092806033807039e-07 2.0589956166420782e-05 +4 100 1 35 5 4.345089833779789 4.3346701508967111 20.564891173839655 0.055701794133937277 8.624887340923556e-08 0.0002903298250726874 -4.6945649468398098 8.6248993086352754e-08 4.78762104281725e-06 +4 100 2 35 1 4.0051745686255105 4.0050287756412137 20.115047125800935 0.00051611850503219259 1.5621620535007706e-09 2.6292646952968977e-06 -4.0097180512848638 1.5626505833126274e-09 8.6741636597980988e-08 +4 100 2 35 3 4.1729334888883667 4.1729333291926638 20.110898670110686 4.989892286033637e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818312768761212 4.0159515435019528e-12 2.2292265020826827e-10 +4 100 2 35 5 4.3192648651884973 4.3192647263053008 20.110897764139928 3.8637084109893749e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960329643829137 3.1036885691353279e-12 1.7228357308550252e-10 +4 100 4 35 1 4.0051745686255105 4.0050287756412137 20.112970982688424 0.0002580861959002867 1.5621620535007706e-09 1.3146323476484488e-06 -4.0099760835939957 1.5626505833126274e-09 8.6741636597980988e-08 +4 100 4 35 3 4.1729334888883667 4.1729333291926638 20.110896663024612 2.4949463606205313e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818315263707142 4.0159515435019528e-12 2.2292265020826827e-10 +4 100 4 35 5 4.3192648651884973 4.3192647263053008 20.110896210039222 1.9318543476032346e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960331575683201 3.1036885691353279e-12 1.7228357308550252e-10 +4 500 0.5 35 1 5.2769648793079975 4.3979519355083525 22.702827326294504 5.4402234338285567 4.7324152396486999e-06 0.031860388069750778 -0.90757734476268048 4.7324173472116991e-06 0.00026269316387519839 +4 500 0.5 35 3 5.6140272091444308 4.6741061358639087 20.941739111739132 4.7056115617438898 3.7151301678076519e-06 0.025011644769527178 -2.0198528404579559 3.7151320940363796e-06 0.00020622437380163084 +4 500 0.5 35 5 5.8702825785273234 4.8735460119823859 19.690403138121891 4.1487503218249628 3.0736699021056409e-06 0.020693094523689365 -2.7958406755803136 3.0736705643127693e-06 0.00017061729471622367 +4 500 1 35 1 5.0061300640459656 4.345782647778142 17.436935307400855 3.0807240119077375 4.1089033786716284e-06 0.013831336596247851 -2.8844829187495438 4.1089053637676234e-06 0.00022808245149972929 +4 500 1 35 3 5.040148139926826 4.543766856116835 15.729122966355986 2.2226648588307207 2.7558764091132632e-06 0.0092767949789141595 -3.7945202635263056 2.7558770154496778e-06 0.00015297679797111728 +4 500 1 35 5 5.0507082932903096 4.6716273695999391 14.63425877381796 1.65334307106018 1.9614924732583415e-06 0.0066027502056798699 -4.3797495225697993 1.9614941981463217e-06 0.00010888116559235758 +4 500 2 35 1 4.2452271984643852 4.1100651526970795 12.634781716456743 0.57909743199277353 1.2736612673836964e-06 0.0021436909164414056 -3.9593424798266956 1.2736636138766865e-06 7.0700172849108328e-05 +4 500 2 35 3 4.1729334888883667 4.1729333291926638 11.587399213430825 7.128316927840217e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818310630336565 4.0159515435019528e-12 2.2292265020826827e-10 +4 500 2 35 5 4.3192648651884973 4.3192647263053008 11.587398925111476 5.5195053949574913e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960327988032153 3.1036885691353279e-12 1.7228357308550252e-10 +4 500 4 35 1 4.0051745686255105 4.0050287756412137 11.588058731101466 0.0003687192206469625 1.5621620535007706e-09 1.3146323476484488e-06 -4.009865450569249 1.5626505833126274e-09 8.6741636597980988e-08 +4 500 4 35 3 4.1729334888883667 4.1729333291926638 11.587398574688621 3.5641585238721518e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818314194494974 4.0159515435019528e-12 2.2292265020826827e-10 +4 500 4 35 5 4.3192648651884973 4.3192647263053008 11.587398430528946 2.7597527685330192e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330747784784 3.1036885691353279e-12 1.7228357308550252e-10 +4 900 0.5 35 1 5.4218059803108645 4.4202651495827521 22.641181992248924 5.7667290659645438 4.9986257952601106e-06 0.033652617022735289 -0.75645196058430209 4.9986273443096752e-06 0.00027747029388341244 +4 900 0.5 35 3 5.735186641536008 4.6924572330862695 20.834604646663415 4.903538396596554 3.8497544181484048e-06 0.025917985536820891 -1.9324093685767556 3.8497553607025467e-06 0.00021369721680280579 +4 900 0.5 35 5 5.8702825785273234 4.8735460119823859 19.41853769307605 4.2042857349746026 3.0736699021056409e-06 0.020693094523689365 -2.7403052624306738 3.0736705643127693e-06 0.00017061729471622367 +4 900 1 35 1 5.0378732031454758 4.3526598668881196 17.357373717309365 3.1534980222122173 4.1911865174630245e-06 0.014108317017526951 -2.8602460472135971 4.191186904279446e-06 0.00023264984203605032 +4 900 1 35 3 5.0601941514148194 4.5497103597692314 15.66634533658064 2.263875290809755 2.7997314955286867e-06 0.0094244193949123197 -3.7834141791659346 2.7997338417599523e-06 0.00015541125960366096 +4 900 1 35 5 5.0654865555556317 4.6769409959785291 14.583085743431475 1.6814977442839694 1.9908781908017643e-06 0.0067016680221890397 -4.373674523037419 1.9908805902758392e-06 0.00011051238358455949 +4 900 2 35 1 4.2489833553929461 4.1115885119073132 12.595490491026544 0.58831250710880489 1.2920736431858946e-06 0.0021746806652608512 -3.9581939652174629 1.2920756982424543e-06 7.1722214723422394e-05 +4 900 2 35 3 4.1729334888883667 4.1729333291926638 11.54872147909351 7.1380206234650245e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818310620632879 4.0159515435019528e-12 2.2292265020826827e-10 +4 900 2 35 5 4.3192648651884973 4.3192647263053008 11.548721194531698 5.5270189980305418e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960327980518546 3.1036885691353279e-12 1.7228357308550252e-10 +4 900 4 35 1 4.0051745686255105 4.0050287756412137 11.549372401013832 0.00036922127692529116 1.5621620535007706e-09 1.3146323476484488e-06 -4.0098649485129698 1.5626505833126274e-09 8.6741636597980988e-08 +4 900 4 35 3 4.1729334888883667 4.1729333291926638 11.548720848675762 3.5690103938890161e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818314189643104 4.0159515435019528e-12 2.2292265020826827e-10 +4 900 4 35 5 4.3192648651884973 4.3192647263053008 11.548720706394853 2.7635095634082063e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330744027985 3.1036885691353279e-12 1.7228357308550252e-10 +4 1500 0.5 35 1 5.449623371780568 4.4241486202264442 22.618696178833254 5.8276876169250897 5.0449299619962966e-06 0.033964353978761748 -0.72688580479238052 5.0449301748517087e-06 0.00028004053149329497 +4 1500 0.5 35 3 5.7582356203441663 4.6956476807831411 20.806046965742397 4.9406857166716893 3.8731474356408131e-06 0.026075476073404897 -1.9148574847056761 3.8731491389301129e-06 0.00021499578900527967 +4 1500 0.5 35 5 5.8702825785273234 4.8735460119823859 19.363725726377293 4.2154824695049751 3.0736699021056409e-06 0.020693094523689365 -2.7291085279003013 3.0736705643127693e-06 0.00017061729471622367 +4 1500 1 35 1 5.0444218533177878 4.3540523607220267 17.337565595966531 3.1688002108981093 4.2078429496343866e-06 0.01416438568077431 -2.8548357286003987 4.2078440163460504e-06 0.00023357446663036641 +4 1500 1 35 3 5.0646404435354739 4.5510136796894862 15.650556237345734 2.2731245256174186 2.8093471428066532e-06 0.0094567874605092639 -3.7807893249556597 2.8093495490660504e-06 0.00015594502076414379 +4 1500 1 35 5 5.068923263964721 4.6781667587694438 14.5700034203666 1.6880910045819122 1.9976563392674605e-06 0.0067244845365454055 -4.3721854984051962 1.9976586525488048e-06 0.00011088862906182651 +4 1500 2 35 1 4.2499368418836836 4.1119746203703178 12.585225411206736 0.59065849378589519 1.296740257548478e-06 0.0021825350132541402 -3.9578944816190278 1.2967422248795227e-06 7.1981250340245496e-05 +4 1500 2 35 3 4.1729334888883667 4.1729333291926638 11.538432714380747 7.1406019186426306e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818310618051584 4.0159515435019528e-12 2.2292265020826827e-10 +4 1500 2 35 5 4.3192648651884973 4.3192647263053008 11.538432430733025 5.5290177325417744e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960327978519816 3.1036885691353279e-12 1.7228357308550252e-10 +4 1500 4 35 1 4.0051745686255105 4.0050287756412137 11.539081545269841 0.0003693548276828551 1.5621620535007706e-09 1.3146323476484488e-06 -4.0098648149622127 1.5626505833126274e-09 8.6741636597980988e-08 +4 1500 4 35 3 4.1729334888883667 4.1729333291926638 11.538432085988063 3.5703010325960349e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818314188352465 4.0159515435019528e-12 2.2292265020826827e-10 +4 1500 4 35 5 4.3192648651884973 4.3192647263053008 11.5384319441642 2.7645089106798082e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330743028642 3.1036885691353279e-12 1.7228357308550252e-10 +6 100 0.5 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 0.5 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 0.5 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 1 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 1 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 1 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 2 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 2 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 2 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 4 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 4 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 100 4 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 0.5 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 0.5 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 0.5 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 1 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 1 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 1 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 2 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 2 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 2 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 4 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 4 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 500 4 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 0.5 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 0.5 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 0.5 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 1 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 1 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 1 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 2 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 2 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 2 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 4 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 4 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 900 4 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 0.5 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 0.5 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 0.5 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 1 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 1 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 1 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 2 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 2 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 2 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 4 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 4 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +6 1500 4 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 +0.5 100 0.5 40 1 0.82641094739989962 0.73372936184098259 39.441595349036596 0.10655990305622698 2.8713492365914783e-06 0.019330996188825163 0.092050258703126164 2.871349236317001e-06 0.00015938657986772141 +0.5 100 0.5 40 3 0.94808278259378109 0.89262157993669611 39.179286955229152 0.093023799404440499 1.7054695331580889e-06 0.011481858293480387 0.06795100225067785 1.7054695970183945e-06 9.4669419762331093e-05 +0.5 100 0.5 40 5 1.0484247140995155 1.0114754122577319 38.931281577659718 0.080111405158991289 1.1279043766681671e-06 0.0075934738027945642 0.042736439156290024 1.1279044608277508e-06 6.2609184614363073e-05 +0.5 100 1 40 1 0.86898749005912834 0.76390214772242526 39.151817923725517 0.091599127424382143 3.2499259809064076e-06 0.010939858159755435 0.073872127599704171 3.2499260743692199e-06 0.00018040111431413933 +0.5 100 1 40 3 0.97072030185290636 0.91066392676931363 38.802794357322512 0.073377513139781136 1.8444439309050058e-06 0.0062087429394606913 0.045840142996146631 1.8444439489186522e-06 0.00010238378844955049 +0.5 100 1 40 5 1.0499580525690284 1.0127618809055869 38.491217823827739 0.05692126442721257 1.1353224291432541e-06 0.003821707452227009 0.019329321488728173 1.1353225251900899e-06 6.3020956158206488e-05 +0.5 100 2 40 1 0.8913261392873888 0.77971638882348815 38.759241365415399 0.071088044712298792 3.4483431962509344e-06 0.0058038837922427932 0.051475164420026358 3.4483432002224716e-06 0.00019141510964321241 +0.5 100 2 40 3 0.95964381186722947 0.90183725413061722 38.341531005382691 0.048950867594641512 1.776455186983928e-06 0.0029899400612419156 0.022640785163462587 1.7764551936977873e-06 9.8609780388442253e-05 +0.5 100 2 40 5 1.006302733255555 0.97611619328134291 38.001419849000982 0.030683016906106531 9.2401220403419279e-07 0.0015551988736675442 -0.0010846545142103592 9.2401233901398201e-07 5.1291276104023427e-05 +0.5 100 4 40 1 0.87500807489840848 0.76816547068151064 38.2990259978192 0.046679894492009044 3.3034170434906172e-06 0.0027799797680489653 0.028458507497810991 3.3034171152908198e-06 0.00018337036443468331 +0.5 100 4 40 3 0.89641839565269366 0.85140409141451356 37.885124020854427 0.024385750447341259 1.3879775315586053e-06 0.0011680479350443319 0.0043229225559268981 1.3879775319931771e-06 7.7045658173365369e-05 +0.5 100 4 40 5 0.90334872374267494 0.88955292851569157 37.593742604465852 0.008492497383687958 4.2483917357509768e-07 0.00035752201180310004 -0.012194941636869332 4.2483919586206183e-07 2.3582525443356193e-05 +0.5 500 0.5 40 1 1.6024075961946591 1.2732854865589038 35.954610115451302 2.591562876624097 9.6392355760492044e-06 0.064894936432389846 2.395210306881483 9.6392358478966311e-06 0.00053506721331649356 +0.5 500 0.5 40 3 1.7546333819966338 1.5238912081437483 34.592707441603537 2.3597011937143111 6.5662645027190212e-06 0.044206546685194706 2.0821434218363462 6.5662650542024136e-06 0.00036448876237593191 +0.5 500 0.5 40 5 1.8636227313929321 1.6837391791159089 33.488167448715998 2.1650917901913513 5.0028135462428066e-06 0.033680810527466305 1.8167613501608391 5.002813568237939e-06 0.00027770266823413486 +0.5 500 1 40 1 1.7279992788680356 1.3574906827125606 33.767756219870407 2.2148897008451027 1.069495335483304e-05 0.03600121153972935 1.9529759996077494 1.0694953403666265e-05 0.0005936693535201923 +0.5 500 1 40 3 1.8440303171182826 1.591657228953234 31.976333481346643 1.889784131482894 7.087785268031068e-06 0.02385880969431748 1.5549969648394533 7.0877855818293141e-06 0.00039343800065663693 +0.5 500 1 40 5 1.9153999736021439 1.7252590485589372 30.618111243401337 1.6342404985090284 5.2419987550175723e-06 0.017645547372593627 1.2483307224952884 5.2419990242332532e-06 0.00029097968494217337 +0.5 500 2 40 1 1.789304403126841 1.3981449790026623 30.916502008001853 1.69101639671563 1.1204588564549348e-05 0.018858369445140546 1.3921385508109674 1.1204588571192809e-05 0.00062195884380753864 +0.5 500 2 40 3 1.8353022043693235 1.5850678158648814 28.89064086587284 1.2989130238029687 7.0370766971634532e-06 0.011844057584477255 0.97004138617449809 7.037077214641129e-06 0.00039062321480106186 +0.5 500 2 40 5 1.8472090199094984 1.6705376297176824 27.506965287114411 1.0226522949237782 4.9267584504284918e-06 0.0082921947994692435 0.68569276771334775 4.9267586783096408e-06 0.00027348091469939722 +0.5 500 4 40 1 1.7364923037144395 1.3631411665058779 27.832456154507486 1.0882221979982973 1.0765789301348972e-05 0.0090599146431730743 0.82138834732116117 1.0765789536326784e-05 0.00059760141750356841 +0.5 500 4 40 3 1.6951228624770818 1.4784590189949876 26.03248725487849 0.72133953649973881 6.2165849885030343e-06 0.005231546688435687 0.47787657284884177 6.2165854527600715e-06 0.00034507829324230204 +0.5 500 4 40 5 1.6485293041709943 1.5093716535505661 24.966475631989493 0.49932788907021441 3.9981237551602313e-06 0.0033646079205781531 0.28042937873934648 3.9981237872830842e-06 0.00022193304397907765 +0.5 900 0.5 40 1 1.6329670891633974 1.2938825124221334 35.908045698779702 2.6916242298645341 9.8974856900088651e-06 0.066633572717066963 2.4805265445067883 9.8974860121250714e-06 0.0005494024985914555 +0.5 900 0.5 40 3 1.7812437215073194 1.5441251783639638 34.537596437341392 2.440284542160073 6.7219908114271773e-06 0.04525495439602778 2.146461006639794 6.7219909495914444e-06 0.00037313299747940298 +0.5 900 0.5 40 5 1.8868258449734145 1.7023693631646837 33.428040565538097 2.2319598410272863 5.1101391990274744e-06 0.034403366933529411 1.8671122746606827 5.1101397916404522e-06 0.00028366027153152662 +0.5 900 1 40 1 1.7522721340360441 1.3736241364054418 33.696192636057084 2.2826893086219937 1.0897204358572898e-05 0.036682026212611567 2.0065440020456533 1.0897204895160318e-05 0.00060489619179352307 +0.5 900 1 40 3 1.862889009471635 1.6058743226271246 31.897223211407596 1.9378743387303667 7.1971898767478738e-06 0.024227086051507498 1.5900577140884042 7.1971898902250158e-06 0.00039951095699278466 +0.5 900 1 40 5 1.930553527098323 1.7373737163839611 30.536623928932599 1.6703802456970576 5.3117847782341844e-06 0.017880460167533717 1.2729735104826623 5.3117847818338949e-06 0.00029485344334354122 +0.5 900 2 40 1 1.8050094893032531 1.4085091633792985 30.825823990191971 1.7277002478545369 1.1334504707081335e-05 0.019077030451623858 1.418803058550264 1.133450495246261e-05 0.00062917041090550154 +0.5 900 2 40 3 1.8461669136917314 1.5932693711125503 28.800373126010093 1.3212116285126148 7.1001913487956415e-06 0.0119502854402369 0.98496534801758018 7.1001916048104155e-06 0.00039412665028090011 +0.5 900 2 40 5 1.8553899627572268 1.6771198860774454 27.419972713929518 1.0376994659350669 4.9646796405555748e-06 0.0083560197055865971 0.69510467581073154 4.9646796817043837e-06 0.00027558588296999075 +0.5 900 4 40 1 1.7449469784134939 1.3687603555431691 27.739282263570185 1.1037303295922309 1.0836232078352398e-05 0.0091191955309013126 0.83193508363490942 1.0836232509386421e-05 0.00060151165747357319 +0.5 900 4 40 3 1.7006714712356192 1.4827052970167656 25.946499257334235 0.72959611216961484 6.2492687996913411e-06 0.0052590516424424073 0.48308494526293955 6.2492691778070512e-06 0.00034689254386938948 +0.5 900 4 40 5 1.6526976741103945 1.5127768943430606 24.885924463015332 0.50446727621466358 4.0177473795896168e-06 0.0033811221172936369 0.283445369732785 4.0177473799575713e-06 0.00022302233582889656 +0.5 1500 0.5 40 1 1.6421930491038013 1.3000875549771691 35.892880176149028 2.7228355884909079 9.9752840946568894e-06 0.067157340653263009 2.5071372806499448 9.9752842323889258e-06 0.00055372102316896617 +0.5 1500 0.5 40 3 1.7892432081877012 1.5501976850802586 34.519476522241547 2.4654017853660446 6.76872534182436e-06 0.04556958872106269 2.1665625351539171 6.7687253488970241e-06 0.00037572719116830554 +0.5 1500 0.5 40 5 1.8938140312581182 1.7079728036231181 33.408188598526934 2.2528434454819952 5.1424190958385105e-06 0.034620687263037832 1.8829188269754074 5.1424197547046107e-06 0.00028545210961446632 +0.5 1500 1 40 1 1.7595508345125934 1.3784527151789858 33.672972061726838 2.3038240839862998 1.0957734809722343e-05 0.036885783022400892 2.0233086930740463 1.0957735359002027e-05 0.00060825619533733154 +0.5 1500 1 40 3 1.8685901943662899 1.6101667145138081 31.871428742976519 1.9529652662273391 7.2302202318443615e-06 0.024338272399087375 1.6011425466269793 7.2302203504686957e-06 0.00040134445464716604 +0.5 1500 1 40 5 1.9351879012322015 1.7410753011040376 30.509935691577638 1.6818150594222296 5.3331071019824753e-06 0.017952235093736075 1.2808465794703032 5.333107173575261e-06 0.00029603703433667838 +0.5 1500 2 40 1 1.8097864006306468 1.4116573696934016 30.796389071685788 1.739277990738382 1.137396715519187e-05 0.019143449438933462 1.4272879842528317 1.1373967528406852e-05 0.00063136095078583686 +0.5 1500 2 40 3 1.849546204503733 1.5958184370841315 28.770779671039058 1.3283625587728864 7.1198073485177226e-06 0.011983301000573068 0.98979963336462484 7.1198075149894157e-06 0.00039521551568078912 +0.5 1500 2 40 5 1.8579824310665185 1.679204783096655 27.391205063306813 1.0425887308365263 4.9766908610747328e-06 0.0083762357119783002 0.69819482039318026 4.9766908703433222e-06 0.00027625261561717025 +0.5 1500 4 40 1 1.7476098451690487 1.3705289613928189 27.708627998664607 1.108753791651711 1.0858403357251027e-05 0.0091378536978716039 0.83538274132851376 1.0858403836078269e-05 0.00060274237224969577 +0.5 1500 4 40 3 1.7024664537773213 1.4840785288451843 25.91781997310094 0.73232154548096995 6.2598385862739184e-06 0.0052679466116410615 0.4848186007673021 6.259838929079576e-06 0.00034747926334052602 +0.5 1500 4 40 5 1.6540695672444434 1.513897419460529 24.858817213725271 0.50618427395290455 4.0242046758523892e-06 0.0033865562337646949 0.28446036185740142 4.0242046759043742e-06 0.00022338077579263802 +1 100 0.5 40 1 1.1658488712147033 1.1186755320400086 39.075823364546665 0.087650571643142605 1.4270559359309748e-06 0.0096074739036165757 0.030794469883556011 1.4270559504079458e-06 7.9214873738992281e-05 +1 100 0.5 40 3 1.3006282107779203 1.2740817888612774 38.704228201045652 0.068191132847318148 7.9184578596995918e-07 0.0053310017728436894 -0.019195996564377829 7.9184583175218824e-07 4.3954806092266904e-05 +1 100 0.5 40 5 1.4118523915741399 1.3961418335949038 38.36546396604917 0.050228064020054308 4.6237374780488524e-07 0.0031128728761811429 -0.070144334503076805 4.6237408432814699e-07 2.566606074538701e-05 +1 100 1 40 1 1.1769554889300906 1.1264972931834643 38.679854475345699 0.06690585624689005 1.5251534771956347e-06 0.0051339516070223199 0.0078852394240533294 1.525153500632725e-06 8.4660199868594229e-05 +1 100 1 40 3 1.2853063657973667 1.2619305650945525 38.205091572646126 0.04164898619759283 6.9828604310715309e-07 0.0023505613085989599 -0.04177481496186744 6.9828625713246374e-07 3.8761379801968566e-05 +1 100 1 40 5 1.3703165913479525 1.3614426618212794 37.79083375412263 0.019260845719620612 2.6237241785210685e-07 0.00088319458756829883 -0.087896214201050635 2.6237246157085168e-07 1.4564111105792489e-05 +1 100 2 40 1 1.156879116769078 1.1123555904369062 38.185965354262649 0.040622575773435088 1.34779269988049e-06 0.0022684610437395392 -0.01452838324347544 1.3477927848634272e-06 7.481503107762571e-05 +1 100 2 40 3 1.2199993690638178 1.2100543543552977 37.651581295254175 0.011660476296718514 2.9884223738128818e-07 0.00050297940757768392 -0.056322176640553667 2.9884239393321579e-07 1.6588531442310065e-05 +1 100 2 40 5 1.3159278559925163 1.3159273981189901 37.439292743848625 5.7928136509843853e-07 1.3615413776690843e-11 2.2916013530535145e-08 -0.09147886194414126 1.365615781286689e-11 7.5804373093904466e-10 +1 100 4 40 1 1.0820354137579629 1.0595214507170725 37.679836087287995 0.013205681185652018 6.8513058584780618e-07 0.00057656939528163639 -0.029141847404885804 6.8513070409949123e-07 3.803112429084048e-05 +1 100 4 40 3 1.1712485243954203 1.1712479486414524 37.439288940128719 3.6956557192269202e-07 1.7372492931055916e-11 1.4619764393380111e-08 -0.057900645075049537 1.7372199914064517e-11 9.6431861859919599e-10 +1 100 4 40 5 1.3159278559925163 1.3159273981189901 37.439287490502039 2.8964127585240362e-07 1.3615413776690843e-11 1.1458006765267572e-08 -0.091479151584230506 1.365615781286689e-11 7.5804373093904466e-10 +1 500 0.5 40 1 1.864462668361714 1.5987260627187547 35.065932970383727 2.4413041821776909 7.444886450116098e-06 0.050121758008186947 2.0923849100223069 7.4448864839880841e-06 0.00041326042098185315 +1 500 0.5 40 3 2.0191631320711605 1.8310552078957709 33.55129666560839 2.1763670889065074 5.0780968551815359e-06 0.034187645899364252 1.7070920540456629 5.0780974117124993e-06 0.00028188162152164859 +1 500 0.5 40 5 2.1300317655335337 1.9833762510443314 32.341383589193171 1.9571697473598841 3.8452041675605965e-06 0.025887351549268918 1.3864599723571021 3.845204248611846e-06 0.00021344458776640835 +1 500 1 40 1 1.9633413221233667 1.6639475722654149 32.659192396343492 2.0153705485779052 8.2619448173134766e-06 0.027811250150358083 1.5923015078578535 8.2619455319824097e-06 0.00045861479500318675 +1 500 1 40 3 2.0716871080054422 1.8703945480958784 30.73510322362965 1.6565426204910429 5.380631539711262e-06 0.018112211231940321 1.1408375452158643 5.3806315916023824e-06 0.00029867508141006839 +1 500 1 40 5 2.1364853119449463 1.988502444861548 29.294836207203627 1.378357268825114 3.874714502376539e-06 0.013043013076169941 0.80133877408511212 3.8747145024188813e-06 0.00021508268123335449 +1 500 2 40 1 1.9824534333394439 1.6764518814191596 29.650059309903341 1.4476886627075838 8.4185739626261551e-06 0.014169246561248476 1.0091593769653635 8.4185743138621885e-06 0.00046730914870175903 +1 500 2 40 3 2.0084200289211394 1.8229793786804609 27.571901905573021 1.0357617290572878 5.0159870559698587e-06 0.0084423748795926495 0.57562838000838945 5.0159872555604664e-06 0.00027843393036694236 +1 500 2 40 5 2.0050703261324809 1.8834634115670827 26.176353341627351 0.75103925785499559 3.2699509178703435e-06 0.0055036329198006207 0.2937318539651132 3.2699510190427103e-06 0.00018151268493159646 +1 500 4 40 1 1.8726818361643027 1.6041801703310354 26.593442568454776 0.83678148920706219 7.5132182834312133e-06 0.0063227241810207956 0.48206434194608239 7.5132185136099951e-06 0.00041705348396391871 +1 500 4 40 3 1.8044072693605167 1.6678842819692035 24.87595775531825 0.48032154499169799 3.8229216821142859e-06 0.0032171671911832042 0.17181275900044585 3.8229219112223189e-06 0.0002122077108644085 +1 500 4 40 5 1.7402828741304506 1.6681930000864924 23.889624612760265 0.27169549404496696 2.0300558729927627e-06 0.0017083868553773444 0.0026451039768222717 2.0300562012282221e-06 0.00011268699423970149 +1 900 0.5 40 1 1.8907920329560952 1.6161773949653302 35.029898854551298 2.5313511750419146 7.6635218559849229e-06 0.051593693272533131 2.1636279497906843 7.6635224988799025e-06 0.00042539675264390242 +1 900 0.5 40 3 2.0413717907786944 1.8477185319060832 33.506429258914345 2.2468143653738282 5.2062479061961239e-06 0.035050406669523186 1.7582605084837855 5.2062485796648145e-06 0.00028899520286787756 +1 900 0.5 40 5 2.1489170318062203 1.9983674337159949 32.291051712551081 2.0142462109594148 3.9315033605534309e-06 0.026468349969657343 1.42494790597923 3.9315036936279014e-06 0.00021823500936041639 +1 900 1 40 1 1.9834574555619577 1.6771078241939081 32.596487197495961 2.0731407443112597 8.4267901566271964e-06 0.028366150366850362 1.6337889828834071 8.4267904758617813e-06 0.00046776522208502813 +1 900 1 40 3 2.0867647930620916 1.8816420922624835 30.665135849663997 1.6958818935683113 5.4671227532918321e-06 0.018403356819315406 1.1663108215690348 5.4671233091972421e-06 0.00030347617591991352 +1 900 1 40 5 2.1482805405308318 1.997862671951173 29.22275977965613 1.4069345552864907 3.9285976908688625e-06 0.013224393957692968 0.81826903442372911 3.9285979988502988e-06 0.00021807371628366909 +1 900 2 40 1 1.994889766388658 1.6845699781960559 29.568460421623822 1.4767260853246573 8.5202581988822286e-06 0.014340390631645774 1.027936358037338 8.5202582208442327e-06 0.00047295355097664351 +1 900 2 40 3 2.0167670174977874 1.8292548466495868 27.491427945673827 1.0524990487323227 5.0642507018459561e-06 0.0085236071050739676 0.58527332182462133 5.0642511837358738e-06 0.00028111302712938515 +1 900 2 40 5 2.0112239823749793 1.888411382407692 26.099314213761076 0.76180515364656598 3.2984423610623186e-06 0.0055515866807659712 0.29929735426970239 3.2984426542716922e-06 0.00018309423559654135 +1 900 4 40 1 1.8792034967636027 1.6085037406151423 26.509942162279504 0.84806364822690528 7.5673853760784243e-06 0.0063683083200110589 0.48869959551774722 7.5673857955874936e-06 0.00042006027175062411 +1 900 4 40 3 1.8086485055478412 1.671139668659356 24.799140752057699 0.48592404830813063 3.847968164492567e-06 0.0032382449762026946 0.17467269859871115 3.8479685080294919e-06 0.00021359802986563932 +1 900 4 40 5 1.7434614906611845 1.6708018251364001 23.817565968147971 0.27493121879401539 2.0450853012665177e-06 0.0017210348214005001 0.0040122930606937834 2.0450857018012269e-06 0.00011352127126290463 +1 1500 0.5 40 1 1.8987489551946102 1.6214395323064621 35.017580006211574 2.5594546749553557 7.729445470630334e-06 0.052037515684388816 2.185915963347294 7.7294461121836728e-06 0.00042905612612732016 +1 1500 0.5 40 3 2.0480852378561338 1.8527472339222011 33.491133782092589 2.2688356974391373 5.2449207408707412e-06 0.035310766646003633 1.7743525129681972 5.2449212301515974e-06 0.00029114189454074922 +1 1500 0.5 40 5 2.1546583760217874 2.0029189882900109 32.273969951247793 2.0321628385856205 3.957704280900632e-06 0.026644744357675679 1.4371367430858497 3.9577048398375738e-06 0.0002196894165882639 +1 1500 1 40 1 1.9895353175736836 1.6810765432764456 32.575694254692607 2.0912273332353863 8.4765010871293939e-06 0.028533486648316023 1.646874670870742 8.4765012218259538e-06 0.00047052463068698056 +1 1500 1 40 3 2.0913859858681332 1.8850852311349378 30.641958065231961 1.7083259417066219 5.4935992211388277e-06 0.018492481557699968 1.1744566165741128 5.4935999161343262e-06 0.00030494587377931316 +1 1500 1 40 5 2.1519521076672095 2.0007738931121137 29.198831550802076 1.4160732738523767 3.9453561284460785e-06 0.013280805990198005 0.823751520110234 3.9453565825239515e-06 0.00021900397349563982 +1 1500 2 40 1 1.9987320407746696 1.6870751292296058 29.541618045796653 1.4859783954705947 8.5516361812101017e-06 0.014393202707678117 1.0339865327481093 8.551636181484952e-06 0.00047469531953843756 +1 1500 2 40 3 2.0194154331544141 1.8312447500326927 27.464718355935048 1.0579338359433446 5.0795545755254523e-06 0.0085493649543807084 0.58844267035914455 5.0795551394811643e-06 0.00028196253896648149 +1 1500 2 40 5 2.0132167905018399 1.8900131481239431 26.073528243280819 0.76535245042183409 3.3076655792464577e-06 0.005567110218733259 0.30115214855177702 3.3076659412458586e-06 0.0001836062137799533 +1 1500 4 40 1 1.8812982953319497 1.609891724663679 26.482144936420749 0.85176391162543608 7.5847743530960216e-06 0.0063829419565333513 0.49089849132225893 7.5847748281077912e-06 0.0004210255247353756 +1 1500 4 40 3 1.810048164733866 1.6722137166708946 24.773237182626517 0.48779740744529532 3.8562316973810375e-06 0.0032451991251763531 0.1756373080661589 3.8562320772992777e-06 0.00021405673479318776 +1 1500 4 40 5 1.7445282690971098 1.671677255185211 23.79306744986004 0.2760264633016587 2.0501286340548665e-06 0.0017252790215516055 0.0044784216539156541 2.0501290567448308e-06 0.00011380122435441748 +2 100 0.5 40 1 2.0325320903134543 2.0236481686161287 38.008112354277316 0.031044614019532624 2.345106947040098e-07 0.0015788136419599642 -0.44977402837016217 2.3451146654220048e-07 1.301756683553708e-05 +2 100 0.5 40 3 2.1713893130714541 2.1713888619558692 37.439317735149821 1.9571608991242329e-06 1.1500376674256073e-11 7.7424833881928689e-08 -0.61192017900438544 1.2390583932180694e-11 6.8779261349878953e-10 +2 100 0.5 40 5 2.316213588222487 2.3162132275844125 37.439309520040766 1.5042262102582526e-06 8.8388811209760828e-12 5.9506651119143227e-08 -0.77106162208145179 9.7500543226876377e-12 5.4121866903622745e-10 +2 100 1 40 1 2.0049020653879119 2.0049014061797705 37.43930923513436 1.4885180785739749e-06 1.7493157341563757e-11 5.8885236527638684e-08 -0.45716426956877515 1.7589979684931544e-11 9.7640742075667735e-10 +2 100 1 40 3 2.1713893130714541 2.1713888619558692 37.439299986259726 9.7858723302479689e-07 1.1500376674256073e-11 3.8712416940964345e-08 -0.61192115757805154 1.2390583932180694e-11 6.8779261349878953e-10 +2 100 1 40 5 2.316213588222487 2.3162132275844125 37.439295878657177 7.5211711170197759e-07 8.8388811209760828e-12 2.9753325559571613e-08 -0.77106237419055035 9.7500543226876377e-12 5.4121866903622745e-10 +2 100 2 40 1 2.0049020653879119 2.0049014061797705 37.439295736202503 7.4426296059471042e-07 1.7493157341563757e-11 2.9442618263819342e-08 -0.45716501382389313 1.7589979684931544e-11 9.7640742075667735e-10 +2 100 2 40 3 2.1713893130714541 2.1713888619558692 37.439291111726646 4.8929531093477863e-07 1.1500376674256073e-11 1.9356208470482172e-08 -0.61192164686997363 1.2390583932180694e-11 6.8779261349878953e-10 +2 100 2 40 5 2.316213588222487 2.3162132275844125 37.439289057913349 3.760595568280678e-07 8.8388811209760828e-12 1.4876662779785807e-08 -0.77106275024810522 9.7500543226876377e-12 5.4121866903622745e-10 +2 100 4 40 1 2.0049020653879119 2.0049014061797705 37.439288986685682 3.721324626226874e-07 1.7493157341563757e-11 1.4721309131909671e-08 -0.4571653859543911 1.7589979684931544e-11 9.7640742075667735e-10 +2 100 4 40 3 2.1713893130714541 2.1713888619558692 37.439286674438137 2.4464808134894156e-07 1.1500376674256073e-11 9.6781042352410862e-09 -0.61192189151720322 1.2390583932180694e-11 6.8779261349878953e-10 +2 100 4 40 5 2.316213588222487 2.3162132275844125 37.439285647528465 1.8803002932443746e-07 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106293827763273 9.7500543226876377e-12 5.4121866903622745e-10 +2 500 0.5 40 1 2.5355763266375657 2.3517713660663615 32.871030652498476 2.0539208056056411 4.3350905676103986e-06 0.029185449882845937 0.99718532675396676 4.335091069637681e-06 0.00024063786120664341 +2 500 0.5 40 3 2.6856564591487699 2.5537402142116572 31.125869270640312 1.7306433959489635 2.9344248748234897e-06 0.019755644959073032 0.44771272734712064 2.9344248856330231e-06 0.00016288786486999849 +2 500 0.5 40 5 2.7952621215753672 2.693318142992184 29.775781067409568 1.4721156261566226 2.1664716503426102e-06 0.014585496839696777 0.0087844348964745134 2.1664730961472653e-06 0.00012025940028572108 +2 500 1 40 1 2.5599880349266355 2.3669452126418773 29.964967520584995 1.5087626212323086 4.5245288062030517e-06 0.01523040945252052 0.41691422410918455 4.5245291523120727e-06 0.00025115343615387582 +2 500 1 40 3 2.6424417342408719 2.5227620359626419 27.840029267834922 1.0897436029112249 2.6968886935857728e-06 0.0090782313055166614 -0.12554523385662564 2.6968898206043363e-06 0.00014970246020562511 +2 500 1 40 5 2.6878736604231843 2.61093607183851 26.278880858898372 0.77216618608453746 1.6935283378026708e-06 0.0057007328517434171 -0.51428886994436285 1.6935283380702835e-06 9.4006568863185311e-05 +2 500 2 40 1 2.4641548349053886 2.3069314568616019 26.60889929288042 0.83994854154348753 3.7751796542082989e-06 0.006353980088665708 -0.11786067920949339 3.7751802565078782e-06 0.00020955760513504738 +2 500 2 40 3 2.4358639383572909 2.371521665101171 24.477219085492223 0.39631514040453064 1.5366407838479997e-06 0.0025863100139136134 -0.52388413470956652 1.5366417440530419e-06 8.5297904193896304e-05 +2 500 2 40 5 2.3919924863636433 2.3773577801954282 23.081862192346186 0.098815088219374125 3.5153771386452301e-07 0.00059167081805505976 -0.76483641515358802 3.5153843133650894e-07 1.9513651475798442e-05 +2 500 4 40 1 2.2030773857560972 2.1378676407318871 23.673092653697815 0.22552857285856565 1.6627572830856449e-06 0.0013992879328580867 -0.41923301837956517 1.6627572915507457e-06 9.229848967808747e-05 +2 500 4 40 3 2.1713893130714541 2.1713888619558692 22.623846110451488 1.6601009731331828e-06 1.1500376674256073e-11 9.6781042352410862e-09 -0.61192047606431144 1.2390583932180694e-11 6.8779261349878953e-10 +2 500 4 40 5 2.316213588222487 2.3162132275844125 22.623844334701182 1.2759092204994715e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106185039844155 9.7500543226876377e-12 5.4121866903622745e-10 +2 900 0.5 40 1 2.5526677997836398 2.3624034127834634 32.85257584428814 2.1222906444289085 4.4678288923427587e-06 0.030079093894104663 1.0410406091078019 4.4678289314601573e-06 0.00024800604670886247 +2 900 0.5 40 3 2.6994366623871828 2.5635666996706865 31.096061651401527 1.7810384092267788 3.0097634880893349e-06 0.020262852660370371 0.47611849803864037 3.0097639721395721e-06 0.00016706988465942671 +2 900 0.5 40 5 2.8066148998570259 2.7019425124136038 29.739389757629137 1.5111101731687371 2.2159714804507743e-06 0.014918748195879527 0.028385753159476224 2.2159724013286028e-06 0.00012300707195829046 +2 900 1 40 1 2.5718784932193244 2.3743072525859645 29.917048191320649 1.5467602423212212 4.6164329582052063e-06 0.015539776002129062 0.43757059289366085 4.6164339551770324e-06 0.00025625500722603568 +2 900 1 40 3 2.6507975627553169 2.5287708122871084 27.78572468844634 1.1133119892262786 2.742965877937137e-06 0.0092333357184067773 -0.11489924695534093 2.7429672289856731e-06 0.00015226018478965714 +2 900 1 40 5 2.6940598073172324 2.6157197627958997 26.223202484988398 0.78787439705006834 1.7209962986670738e-06 0.005793195140903146 -0.50844159930689914 1.7209964773807459e-06 9.5531305988384455e-05 +2 900 2 40 1 2.4706890016253538 2.3110607345696996 26.545280608968987 0.85546713194086843 3.8267483448945432e-06 0.0064407750133664947 -0.11115600933436154 3.8267486196004909e-06 0.00021242012875939443 +2 900 2 40 3 2.4399259418800439 2.3745422763271944 24.416165266741938 0.4038761472653416 1.5598221760096065e-06 0.0026253264628548463 -0.52166802157009551 1.5598232569712935e-06 8.6584693698101223e-05 +2 900 2 40 5 2.3947785138077222 2.3795965549192637 23.024434270337466 0.10278031467837545 3.6440716377221002e-07 0.00061333130469557503 -0.76439799121193752 3.6440775303014534e-07 2.0228018486269515e-05 +2 900 4 40 1 2.2062471545036249 2.1399644871976613 23.609774724256894 0.22997225883662997 1.6889692527914313e-06 0.0014213465299118212 -0.41813491264417568 1.6889692576632965e-06 9.3753497511146072e-05 +2 900 4 40 3 2.1713893130714541 2.1713888619558692 22.554099439226455 1.666764501973006e-06 1.1500376674256073e-11 9.6781042352410862e-09 -0.6119204694007826 1.2390583932180694e-11 6.8779261349878953e-10 +2 900 4 40 5 2.316213588222487 2.3162132275844125 22.55409767840694 1.2810306269095406e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106184527703514 9.7500543226876377e-12 5.4121866903622745e-10 +2 1500 0.5 40 1 2.5578963104850487 2.365648144848628 32.84515146133532 2.1437568677033609 4.5083363779057753e-06 0.030351805426041861 1.0549429455001407 4.5083366157244436e-06 0.00025025459981817619 +2 1500 0.5 40 3 2.7036969307631491 2.5665994918403072 31.085185488543825 1.7969896880324554 3.0330146067703005e-06 0.020419387881122974 0.4852308395609124 3.0330153631226118e-06 0.00016836055304594015 +2 1500 0.5 40 5 2.8101668288949995 2.7046373517385756 29.726532940722578 1.5235638668923186 2.2314381810517684e-06 0.015022875804796386 0.034745193723861645 2.2314388691323165e-06 0.00012386560472563512 +2 1500 1 40 1 2.5755773985339272 2.3765935559938698 29.90059313739841 1.5588626785513617 4.6449732256393373e-06 0.015635847875582563 0.44424671293810114 4.6449743711239098e-06 0.00025783926567437746 +2 1500 1 40 3 2.6534613406762557 2.5306844729499387 27.767298080060876 1.1209565171739828 2.7576401716888243e-06 0.0092827321333347479 -0.11139012025122019 2.7576415301043381e-06 0.0001530747449405683 +2 1500 1 40 5 2.6960751364808337 2.6172772263760811 26.204319586187204 0.79305390328005343 1.7299390646617949e-06 0.0058232981623605289 -0.50648338090848433 1.7299393477957994e-06 9.6027718445506491e-05 +2 1500 2 40 1 2.4728008019042527 2.3123941464159605 26.523838582633893 0.86055893738253397 3.8434004319476299e-06 0.0064688020317501347 -0.10892301760468914 3.8434006136606619e-06 0.00021334446925676723 +2 1500 2 40 3 2.441282391966265 2.3755505758302058 24.395400823498981 0.4064205220632009 1.5675602104653892e-06 0.0026383502978404596 -0.52091261998102001 1.567561319234027e-06 8.7014228100695359e-05 +2 1500 2 40 5 2.3957315050307755 2.3803621977745841 23.004733133060732 0.10414239361351108 3.6880838507025783e-07 0.00062073897136448008 -0.7642442934360858 3.6880892877539403e-07 2.0472324661415156e-05 +2 1500 4 40 1 2.2073181798688335 2.1406727586075038 23.588160790849322 0.23148265760393194 1.6978230352386741e-06 0.0014287974014639141 -0.41775744294832695 1.697823052092593e-06 9.4244965422847244e-05 +2 1500 4 40 3 2.1713893130714541 2.1713888619558692 22.530138852710195 1.6690536743801943e-06 1.1500376674256073e-11 9.6781042352410862e-09 -0.61192046711161019 1.2390583932180694e-11 6.8779261349878953e-10 +2 1500 4 40 5 2.316213588222487 2.3162132275844125 22.530137096588163 1.2827900275347304e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106184351763452 9.7500543226876377e-12 5.4121866903622745e-10 +3 100 0.5 40 1 3.0049013820550252 3.004900886809561 37.439311415395373 1.6087253635888032e-06 9.4529284748290355e-12 6.3640647397206714e-08 -1.8415925262014645 1.1003398397039095e-11 6.1079091851452102e-10 +3 100 0.5 40 3 3.1718079687688916 3.1718075251234743 37.439306423582863 1.3335049842133628e-06 7.8357082936797437e-12 5.2752916723455878e-08 -2.170437054015359 7.8605668043621887e-12 4.3633454367816762e-10 +3 100 0.5 40 5 3.3170442487608387 3.3170439012574113 37.439299842183338 9.7064367121646455e-07 5.7035115736958624e-12 3.8398171524727497e-08 -2.4731255824798613 6.1738007589111003e-12 3.4270334492984183e-10 +3 100 1 40 1 3.0049013820550252 3.004900886809561 37.439296826344432 8.0436726435095807e-07 9.4529284748290355e-12 3.1820323698603357e-08 -1.8415933305595638 1.1003398397039095e-11 6.1079091851452102e-10 +3 100 1 40 3 3.1718079687688916 3.1718075251234743 37.439294330413375 6.6675564225349149e-07 7.8357082936797437e-12 2.6376458361727939e-08 -2.170437720764701 7.8605668043621887e-12 4.3633454367816762e-10 +3 100 1 40 5 3.3170442487608387 3.3170439012574113 37.439291039688001 4.8532350449548289e-07 5.7035115736958624e-12 1.9199085762363748e-08 -2.473126067800028 6.1738007589111003e-12 3.4270334492984183e-10 +3 100 2 40 1 3.0049013820550252 3.004900886809561 37.439289531759492 4.0218477881381887e-07 9.4529284748290355e-12 1.5910161849301679e-08 -1.8415937327420493 1.1003398397039095e-11 6.1079091851452102e-10 +3 100 2 40 3 3.1718079687688916 3.1718075251234743 37.439288283787747 3.3337860649851336e-07 7.8357082936797437e-12 1.318822918086397e-08 -2.1704380541417367 7.8605668043621887e-12 4.3633454367816762e-10 +3 100 2 40 5 3.3170442487608387 3.3170439012574113 37.43928663841865 2.4266216724910805e-07 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731263104613652 6.1738007589111003e-12 3.4270334492984183e-10 +3 100 4 40 1 3.0049013820550252 3.004900886809561 37.439285884452147 2.0109267584444979e-07 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415939338341523 1.1003398397039095e-11 6.1079091851452102e-10 +3 100 4 40 3 3.1718079687688916 3.1718075251234743 37.439285260464729 1.6668950086895507e-07 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704382208308424 7.8605668043621887e-12 4.3633454367816762e-10 +3 100 4 40 5 3.3170442487608387 3.3170439012574113 37.439284437778589 1.2133118909574137e-07 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731264317923434 6.1738007589111003e-12 3.4270334492984183e-10 +3 500 0.5 40 1 3.3750602896822337 3.2168270610967493 30.626298354476205 1.6358029413745068 2.6257966307137042e-06 0.017677844274077887 -0.96179942950162411 2.6257966415591001e-06 0.00014575612775792951 +3 500 0.5 40 3 3.51902978547737 3.4030047169469873 28.894749450788364 1.2997234917655933 1.7610181644687855e-06 0.011855832440016542 -1.6136840141480597 1.7610183121628566e-06 9.7752889934102507e-05 +3 500 0.5 40 5 3.628879003776063 3.539226045208351 27.609579902669395 1.0433618067930435 1.2670394345322781e-06 0.0085301830121890607 -2.1159226814519236 1.267041242941821e-06 7.0332569688693927e-05 +3 500 1 40 1 3.3150363126405229 3.184241655012487 27.145325895136885 0.94939206996262415 2.2225715608698917e-06 0.0074815912019760801 -1.5194596934644191 2.2225718727946098e-06 0.00012337340398526839 +3 500 1 40 3 3.3694972450164968 3.306336833346184 25.019278112441746 0.51040398401311604 1.025303731670852e-06 0.0034513639575319576 -2.0751849305842787 1.0253039953584929e-06 5.6913904821453943e-05 +3 500 1 40 5 3.3955332463908858 3.3747292695714819 23.464486055961483 0.18092885316216023 3.2927696976854895e-07 0.001108407811656478 -2.4610191755871909 3.2927834292788766e-07 1.8278009599105616e-05 +3 500 2 40 1 3.0762480835047907 3.0477047978135516 23.3073843477531 0.14726197072474623 5.3096688217890851e-07 0.00089366687313672025 -1.8321554109601677 5.3096837500467216e-07 2.9473681654436425e-05 +3 500 2 40 3 3.1718079687688916 3.1718075251234743 22.623848893369409 2.26219805554706e-06 7.8357082936797437e-12 1.318822918086397e-08 -2.1704361253222877 7.8605668043621887e-12 4.3633454367816762e-10 +3 500 2 40 5 3.3170442487608387 3.3170439012574113 22.623846048166005 1.6466252219515809e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731249064983105 6.1738007589111003e-12 3.4270334492984183e-10 +3 500 4 40 1 3.0049013820550252 3.004900886809561 22.623844744393725 1.364548089188844e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415927703787389 1.1003398397039095e-11 6.1079091851452102e-10 +3 500 4 40 3 3.1718079687688916 3.1718075251234743 22.623843665384008 1.1310993675017755e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704372564209757 7.8605668043621887e-12 4.3633454367816762e-10 +3 500 4 40 5 3.3170442487608387 3.3170439012574113 22.623842242781656 8.2331279216418807e-07 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731257298107403 6.1738007589111003e-12 3.4270334492984183e-10 +3 900 0.5 40 1 3.3862741110926282 3.2228337087016046 30.610190710700941 1.6849846117135834 2.7001033991600714e-06 0.018178105210412399 -0.93688178527320431 2.7001039118222849e-06 0.00014988087215222232 +3 900 0.5 40 3 3.5281262468172576 3.4087329795978345 28.868361895509093 1.3350429868153371 1.80458523303474e-06 0.012149142228207441 -1.5985918028718311 1.8045861695325203e-06 0.00010017131110366473 +3 900 0.5 40 5 3.6365003449559219 3.5444077123650821 27.577903475657685 1.0703917551230515 1.2965494459000334e-06 0.0087288554376859489 -2.1060622161441898 1.2965505480928018e-06 7.1970610496408652e-05 +3 900 1 40 1 3.3216805408649481 3.1878843037511926 27.102826013458177 0.97185293086497859 2.2676562120504064e-06 0.0076333545627401663 -1.5111528627600888 2.2676570973957685e-06 0.00012587605314436684 +3 900 1 40 3 3.3739575652834874 3.3092865162923957 24.973575361022583 0.52317728268169228 1.0477663442152303e-06 0.003526977308905734 -2.072042485327164 1.0477663816953495e-06 5.816077611409101e-05 +3 900 1 40 5 3.3986692944668988 3.3770109281653644 23.418974916612726 0.18860027466093321 3.4229627144519603e-07 0.0011522332139943681 -2.4601588359528574 3.4229790286675325e-07 1.9000716229073176e-05 +3 900 2 40 1 3.0790564264737443 3.0493715676917517 23.257197463454901 0.15345456153237969 5.5163633826979147e-07 0.00092845549897035962 -1.8314745399389927 5.5163765961506404e-07 3.0621019129340219e-05 +3 900 2 40 3 3.1718079687688916 3.1718075251234743 22.554102198745149 2.2712783667167002e-06 7.8357082936797437e-12 1.318822918086397e-08 -2.1704361162419765 7.8605668043621887e-12 4.3633454367816762e-10 +3 900 2 40 5 3.3170442487608387 3.3170439012574113 22.554099377464684 1.6532346616138227e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731248998888709 6.1738007589111003e-12 3.4270334492984183e-10 +3 900 4 40 1 3.0049013820550252 3.004900886809561 22.554098084654715 1.3700252834425442e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415927649015447 1.1003398397039095e-11 6.1079091851452102e-10 +3 900 4 40 3 3.1718079687688916 3.1718075251234743 22.554097014717499 1.1356395188677482e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704372518808244 7.8605668043621887e-12 4.3633454367816762e-10 +3 900 4 40 5 3.3170442487608387 3.3170439012574113 22.554095604076615 8.2661750910872911e-07 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731257265060234 6.1738007589111003e-12 3.4270334492984183e-10 +3 1500 0.5 40 1 3.3897773030301073 3.224704902223082 30.603583620767722 1.7006248756286957 2.7232499377903663e-06 0.018333936359178502 -0.92883445131809683 2.7232507731494923e-06 0.00015116573817094045 +3 1500 0.5 40 3 3.5310161531204773 3.4105490543248287 28.858739875173661 1.3464237726246808 1.8183969113320909e-06 0.012242127608433885 -1.5936428698064531 1.8183981379647406e-06 0.00010093800377267503 +3 1500 0.5 40 5 3.6389574255284893 3.5460755340081915 27.566719174243595 1.0792037994672632 1.3060474359434959e-06 0.0087927994564043505 -2.1027879707077868 1.3060482896139837e-06 7.2497823459005486e-05 +3 1500 1 40 1 3.3238286905190941 3.189060126418422 27.088187197114749 0.97919988822575599 2.2822087082370826e-06 0.0076823409843042112 -1.5083874383104985 2.2822097918760671e-06 0.00012668386299617359 +3 1500 1 40 3 3.375443262505387 3.3102681563520733 24.957932693569653 0.52745837822118391 1.055241570038758e-06 0.0035521403159101974 -2.0709716081844918 1.0552415749408401e-06 5.8575718842122682e-05 +3 1500 1 40 5 3.3997408948105003 3.3777901623195454 23.403363016935089 0.19123000358653952 3.4674256880667796e-07 0.0011672002817849829 -2.4598575691804743 3.4674427880666458e-07 1.9247531435285295e-05 +3 1500 2 40 1 3.0800164068939933 3.049941003507147 23.239980082643761 0.15557873687087742 5.5869776027103516e-07 0.00094034053197628617 -1.8312359122879136 5.586990163541707e-07 3.1012990083495462e-05 +3 1500 2 40 3 3.1718079687688916 3.1718075251234743 22.530141604867062 2.2743977892147882e-06 7.8357082936797437e-12 1.318822918086397e-08 -2.170436113122554 7.8605668043621887e-12 4.3633454367816762e-10 +3 1500 2 40 5 3.3170442487608387 3.3170439012574113 22.530138791113178 1.6555052506639356e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731248976182818 6.1738007589111003e-12 3.4270334492984183e-10 +3 1500 4 40 1 3.0049013820550252 3.004900886809561 22.530137501752151 1.3719069102968717e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415927630199178 1.1003398397039095e-11 6.1079091851452102e-10 +3 1500 4 40 3 3.1718079687688916 3.1718075251234743 22.530136434669288 1.1371992316711044e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704372503211116 7.8605668043621887e-12 4.3633454367816762e-10 +3 1500 4 40 5 3.3170442487608387 3.3170439012574113 22.530135027791694 8.2775280585423161e-07 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731257253707266 6.1738007589111003e-12 3.4270334492984183e-10 +4 100 0.5 40 1 4.0051745686255105 4.0050287756412137 37.4440955524271 0.00026535634071267467 1.5621620535007706e-09 1.0517058781187591e-05 -4.0099688134491824 1.5626505833126274e-09 8.6741636597980988e-08 +4 100 0.5 40 3 4.1729334888883667 4.1729333291926638 37.439286898082521 2.56978581081313e-07 1.510000983184767e-12 1.0165890961322992e-08 -4.3818315188867683 4.0159515435019528e-12 2.2292265020826827e-10 +4 100 0.5 40 5 4.3192648651884973 4.3192647263053008 37.439285846140443 1.9898038194909873e-07 1.1692042524380496e-12 7.8715200017495467e-09 -4.6960331517733724 3.1036885691353279e-12 1.7228357308550252e-10 +4 100 1 40 1 4.0051745686255105 4.0050287756412137 37.441691054744048 0.0001328029889315907 1.5621620535007706e-09 5.2585293905937953e-06 -4.0101013668009635 1.5626505833126274e-09 8.6741636597980988e-08 +4 100 1 40 3 4.1729334888883667 4.1729333291926638 37.439284567610713 1.2848940578180645e-07 1.510000983184767e-12 5.0829454806614958e-09 -4.381831647375944 4.0159515435019528e-12 2.2292265020826827e-10 +4 100 1 40 5 4.3192648651884973 4.3192647263053008 37.439284041638899 9.9490260030421496e-08 1.1692042524380496e-12 3.9357600008747733e-09 -4.6960332512634952 3.1036885691353279e-12 1.7228357308550252e-10 +4 100 2 40 1 4.0051745686255105 4.0050287756412137 37.440487186620786 6.6432741138822138e-05 1.5621620535007706e-09 2.6292646952968977e-06 -4.0101677370487572 1.5626505833126274e-09 8.6741636597980988e-08 +4 100 2 40 3 4.1729334888883667 4.1729333291926638 37.439283402373334 6.4244733977147916e-08 1.510000983184767e-12 2.5414727403307479e-09 -4.3818317116206158 4.0159515435019528e-12 2.2292265020826827e-10 +4 100 2 40 5 4.3192648651884973 4.3192647263053008 37.439283139387172 4.9745146668556117e-08 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960333010086082 3.1036885691353279e-12 1.7228357308550252e-10 +4 100 4 40 1 4.0051745686255105 4.0050287756412137 37.4398848471346 3.3224187497182811e-05 1.5621620535007706e-09 1.3146323476484488e-06 -4.0102009456023984 1.5626505833126274e-09 8.6741636597980988e-08 +4 100 4 40 3 4.1729334888883667 4.1729333291926638 37.43928281975424 3.2122373649912106e-08 1.510000983184767e-12 1.2707363701653739e-09 -4.3818317437429766 4.0159515435019528e-12 2.2292265020826827e-10 +4 100 4 40 5 4.3192648651884973 4.3192647263053008 37.439282688261144 2.4872580439705416e-08 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960333258811744 3.1036885691353279e-12 1.7228357308550252e-10 +4 500 0.5 40 1 4.3536763994440459 4.1525589324912531 28.95509833650835 1.3116211489977716 1.7868487203000963e-06 0.012029733395695153 -3.4565883501503918 1.7868496711260284e-06 9.9186770531558611e-05 +4 500 0.5 40 3 4.505571771997241 4.3421106931956688 27.594483741171317 1.0403173032538313 1.2618048954446951e-06 0.0084949421387129943 -4.0372720424043376 1.2618072798620205e-06 7.0042036073384437e-05 +4 500 0.5 40 5 4.6300816515151269 4.4905187174582295 26.650506940500648 0.84847013368005664 9.5634152605955142e-07 0.0064384485731934235 -4.4701096109346583 9.5634256306959856e-07 5.3085904139306051e-05 +4 500 1 40 1 4.195015964332149 4.0893449278272733 25.014816912143125 0.50946849647494741 1.023119835511083e-06 0.0034440125549572921 -3.9204627842302182 1.0231202872582728e-06 5.6792688718194441e-05 +4 500 1 40 3 4.235866947634813 4.2074908491936434 23.289580554058848 0.14344236796095311 2.5832195494916304e-07 0.00086955997253402098 -4.3748643528771058 2.583245517474864e-07 1.4339414473909874e-05 +4 500 1 40 5 4.3192648651884973 4.3192647263053008 22.623841557770625 6.7510749524046787e-07 1.1692042524380496e-12 3.9357600008747733e-09 -4.6960326756462596 3.1036885691353279e-12 1.7228357308550252e-10 +4 500 2 40 1 4.0051745686255105 4.0050287756412137 22.625922765100462 0.00045094815288138079 1.5621620535007706e-09 2.6292646952968977e-06 -4.0097832216370142 1.5626505833126274e-09 8.6741636597980988e-08 +4 500 2 40 3 4.1729334888883667 4.1729333291926638 22.623840452342861 4.3594309939720688e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818313399222504 4.0159515435019528e-12 2.2292265020826827e-10 +4 500 2 40 5 4.3192648651884973 4.3192647263053008 22.623839997583346 3.3755378003874625e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960330131999743 3.1036885691353279e-12 1.7228357308550252e-10 +4 500 4 40 1 4.0051745686255105 4.0050287756412137 22.624880657082031 0.00022548760051721572 1.5621620535007706e-09 1.3146323476484488e-06 -4.0100086821893779 1.5626505833126274e-09 8.6741636597980988e-08 +4 500 4 40 3 4.1729334888883667 4.1729333291926638 22.62383944486939 2.179715612449229e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818315578937881 4.0159515435019528e-12 2.2292265020826827e-10 +4 500 4 40 5 4.3192648651884973 4.3192647263053008 22.623839217489618 1.6877689734684509e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960331819768575 3.1036885691353279e-12 1.7228357308550252e-10 +4 900 0.5 40 1 4.3637327274983706 4.1563434014800107 28.931917887210592 1.3479611117059611 1.8325094330520886e-06 0.012337138379017764 -3.4412044656890521 1.8325115034941183e-06 0.00010172142678290971 +4 900 0.5 40 3 4.5144813876985301 4.3461790208466891 27.56523524984128 1.0677717873923664 1.2920582594833005e-06 0.0086986190922080896 -4.0274599958043993 1.2920608726634458e-06 7.1721391765942034e-05 +4 900 0.5 40 5 4.638292703539868 4.4946151390143623 26.618468119582054 0.8707900078578974 9.7914910686817967e-07 0.0065919977312231485 -4.4632466480076278 9.7915106182721694e-07 5.4351987889382015e-05 +4 900 1 40 1 4.1997398824702561 4.0913225266145314 24.97211671715986 0.52286607226929904 1.0470414452766138e-06 0.0035245371636177451 -3.9173257085682738 1.0470415415199225e-06 5.8120540744930474e-05 +4 900 1 40 3 4.2391803280748945 4.2092778560550723 23.247012506736219 0.15123986208067386 2.7167222039445578e-07 0.00091449946076379717 -4.3741988005384949 2.7167481390867607e-07 1.5080478152021986e-05 +4 900 1 40 5 4.3192648651884973 4.3192647263053008 22.554094924825275 6.7781732759897295e-07 1.1692042524380496e-12 3.9357600008747733e-09 -4.6960326729364272 3.1036885691353279e-12 1.7228357308550252e-10 +4 900 2 40 1 4.0051745686255105 4.0050287756412137 22.556158632049044 0.00045275889692986127 1.5621620535007706e-09 2.6292646952968977e-06 -4.0097814108929661 1.5626505833126274e-09 8.6741636597980988e-08 +4 900 2 40 3 4.1729334888883667 4.1729333291926638 22.554093828692132 4.3769294411077908e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818313381724057 4.0159515435019528e-12 2.2292265020826827e-10 +4 900 2 40 5 4.3192648651884973 4.3192647263053008 22.554093377756288 3.3890869088892828e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960330118450635 3.1036885691353279e-12 1.7228357308550252e-10 +4 900 4 40 1 4.0051745686255105 4.0050287756412137 22.555125286977262 0.00022639285881664861 1.5621620535007706e-09 1.3146323476484488e-06 -4.0100077769310793 1.5626505833126274e-09 8.6741636597980988e-08 +4 900 4 40 3 4.1729334888883667 4.1729333291926638 22.554092829689655 2.1884648315761979e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818315570188666 4.0159515435019528e-12 2.2292265020826827e-10 +4 900 4 40 5 4.3192648651884973 4.3192647263053008 22.554092604221722 1.6945435454829294e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960331812994003 3.1036885691353279e-12 1.7228357308550252e-10 +4 1500 0.5 40 1 4.366934460276565 4.1575427591091447 28.923283054950254 1.359664346361741 1.8469786694138055e-06 0.012434550685886989 -3.4361599688260935 1.8469809993480878e-06 0.00010252461833739039 +4 1500 0.5 40 3 4.5173626750714782 4.3474894543984455 27.554825621353523 1.0767249631310905 1.3018022685847127e-06 0.008764219403170917 -4.0241995430501323 1.3018048073950226e-06 7.2262270740772839e-05 +4 1500 0.5 40 5 4.6409823322218955 4.4959521005442813 26.60726167414553 0.87814422644582146 9.8659223976078775e-07 0.0066421076836268231 -4.4609433930393489 9.8659443310006364e-07 5.4765164202057382e-05 +4 1500 1 40 1 4.2013164989582537 4.0919812504997672 24.957467131890393 0.52735850263919559 1.0550091041586724e-06 0.0035513577923173335 -3.9162554138641088 1.0550091343165527e-06 5.8562816226286578e-05 +4 1500 1 40 3 4.240317751198468 4.2098905500083266 23.232394769438834 0.15392213201624028 2.7624934286238547e-07 0.00092990691030977578 -4.3739635089003457 2.7625191310995304e-07 1.5334549714679602e-05 +4 1500 1 40 5 4.3192648651884973 4.3192647263053008 22.53013435035243 6.7874825582237008e-07 1.1692042524380496e-12 3.9357600008747733e-09 -4.696032672005499 3.1036885691353279e-12 1.7228357308550252e-10 +4 1500 2 40 1 4.0051745686255105 4.0050287756412137 22.532192551855644 0.0004533809420306234 1.5621620535007706e-09 2.6292646952968977e-06 -4.0097807888478645 1.5626505833126274e-09 8.6741636597980988e-08 +4 1500 2 40 3 4.1729334888883667 4.1729333291926638 22.530133257143525 4.3829407703199763e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818313375712723 4.0159515435019528e-12 2.2292265020826827e-10 +4 1500 2 40 5 4.3192648651884973 4.3192647263053008 22.530132807410702 3.3937415810925131e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960330113795967 3.1036885691353279e-12 1.7228357308550252e-10 +4 1500 4 40 1 4.0051745686255105 4.0050287756412137 22.531161963673796 0.00022670384559031476 1.5621620535007706e-09 1.3146323476484488e-06 -4.0100074659443052 1.5626505833126274e-09 8.6741636597980988e-08 +4 1500 4 40 3 4.1729334888883667 4.1729333291926638 22.53013226080617 2.1914705028436288e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818315567182999 4.0159515435019528e-12 2.2292265020826827e-10 +4 1500 4 40 5 4.3192648651884973 4.3192647263053008 22.530132035939751 1.6968708749232064e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960331810666673 3.1036885691353279e-12 1.7228357308550252e-10 +6 100 0.5 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 0.5 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 0.5 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 1 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 1 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 1 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 2 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 2 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 2 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 4 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 4 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 100 4 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 0.5 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 0.5 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 0.5 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 1 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 1 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 1 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 2 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 2 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 2 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 4 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 4 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 500 4 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 0.5 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 0.5 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 0.5 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 1 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 1 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 1 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 2 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 2 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 2 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 4 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 4 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 900 4 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 0.5 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 0.5 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 0.5 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 1 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 1 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 1 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 2 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 2 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 2 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 4 40 1 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 4 40 3 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 +6 1500 4 40 5 5.8702829999999997 5.8702829999999997 8.9954794232730979 -3.1707025955141233 0 0 -10.115293908969731 0 0 diff --git a/tests/cpp/test_golden.cpp b/tests/cpp/test_golden.cpp index 84087de..594eed3 100644 --- a/tests/cpp/test_golden.cpp +++ b/tests/cpp/test_golden.cpp @@ -44,7 +44,7 @@ const char *kGoldenPath = "golden/operating_points.tsv"; struct Row { // inputs - double psi_soil, ppfd, vpd; + double psi_soil, ppfd, vpd, leaf_temp; int layers; // outputs double psi_stem, opt_root_psi, ci, assim, transpiration, gc, profit, e_up, uptake; @@ -58,9 +58,22 @@ struct Row { // Trait values and fixed drivers from plant's tests/testthat/test-leaf.r. const double kTheta = 0.000157, kKs = 1.0, kH = 5.0; const double kAreaLeaf = 0.05; -const double kCa = 40.0, kO2 = 21.0, kTleaf = 25.0, kPatm = 101.3; +const double kCa = 40.0, kO2 = 21.0, kPatm = 101.3; +// ⚠️ LEAF TEMPERATURE IS A GRID AXIS, NOT A FIXED DRIVER, and it was fixed at 25 C +// until #41. That single value made this whole file blind to every temperature +// response in the model: the reference values of Vcmax, Jmax and R_d are DEFINED at +// 25 C, so a change to any response curve is inert there BY CONSTRUCTION and a +// bit-identical run said nothing about it. #41 changed R_d's shape at every +// temperature except 25 C and this file did not move a bit. +// +// 40 C is in the list deliberately -- it is where the response bites hardest -- and +// the extra shut-down rows at the hot end are a feature rather than noise: they pin +// the temperature at which the model stops having an operating point, which is a +// limit a caller needs and which moved in #41. +const double kLeafTemps[] = {15.0, 25.0, 35.0, 40.0}; -Row solve(double psi_soil, double ppfd, double vpd, int layers) { +Row solve(double psi_soil, double ppfd, double vpd, int layers, + double leaf_temp) { phylloptim::Leaf l; l.setup_transpiration(100); l.setup_root_vulnerability(100); @@ -76,7 +89,7 @@ Row solve(double psi_soil, double ppfd, double vpd, int layers) { } l.set_physiology(fixture::root_network(root, depth), ppfd, ps, depth, kKs * kTheta / kH, vpd, kCa, - kTleaf, kO2, kPatm); + leaf_temp, kO2, kPatm); l.find_root_collar_psi(); double uptake = 0.0; @@ -85,7 +98,8 @@ Row solve(double psi_soil, double ppfd, double vpd, int layers) { uptake += s; } } - return Row{psi_soil, ppfd, vpd, layers, l.opt_psi_stem_, + return Row{psi_soil, ppfd, vpd, leaf_temp, layers, + l.opt_psi_stem_, l.opt_root_psi_, l.ci_, l.assim_colimited_, l.transpiration_, l.stom_cond_CO2_, l.profit_, l.E_up_, uptake, l.operating_point_kind()}; @@ -97,12 +111,19 @@ std::vector run_grid() { const double vpds[] = {0.5, 1.0, 2.0, 4.0}; const int layer_counts[] = {1, 3, 5}; + // ⚠️ TEMPERATURE IS THE OUTERMOST LOOP ON PURPOSE. It makes the file four + // contiguous copies of the original 288-point grid, so the 25 C block is + // byte-identical to the pre-#41 file's rows in all nine output columns -- which + // is what makes a regeneration checkable as an ADDITION rather than taken on + // trust. Reordering these loops rewrites every row without changing any value. std::vector rows; - for (double p : psi_soils) { - for (double q : ppfds) { - for (double d : vpds) { - for (int n : layer_counts) { - rows.push_back(solve(p, q, d, n)); + for (double t : kLeafTemps) { + for (double p : psi_soils) { + for (double q : ppfds) { + for (double d : vpds) { + for (int n : layer_counts) { + rows.push_back(solve(p, q, d, n, t)); + } } } } @@ -116,11 +137,12 @@ std::vector run_grid() { // // `Leaf::operating_point_kind()` says which branch of the collar solve produced // the point, and the grid's split between those branches is already an -// established number: 240 of the 288 points are feasible, of which 198 sit at an -// interior profit maximum and 42 at a constrained optimum pinned to a bracket +// established number AT 25 C: 240 of those 288 points are feasible, of which 198 sit +// at an interior profit maximum and 42 at a constrained optimum pinned to a bracket // bound (24 wet, 18 dry); the remaining 48 shut down. Those figures were measured // when PLAN 11a replaced the collar solver and are quoted in the developer guide -// and in maximise_profit_over_collar's own comment. +// and in maximise_profit_over_collar's own comment. The other three temperatures +// have no such history, so their counts were measured when the axis was added. // // So this asserts the classification against numbers that already exist rather // than inventing reference values for it. It is a cheap test with a specific @@ -129,44 +151,81 @@ std::vector run_grid() { // not reproduce this split, because dprofit's shut-down sentinel is exactly 0.0 // and would move all 48 shutdown points into `interior`. // -// Three kinds are expected to be EMPTY here: `shade-death` because the grid's -// minimum assim_max_ is 3.71 (it is reached by light, not by drying); -// `solver-refused` and `non-finite-gradient` because both bracket endpoints -// admit a usable gradient on all 240 feasible rows. +// Three kinds are expected to be EMPTY here: `shade-death` because assim_max_ never +// gets there (it is reached by light, not by drying, and not by heat either at 40 C); +// `solver-refused` and `non-finite-gradient` because both bracket endpoints admit a +// usable gradient on every feasible row. +// +// ⚠️ The hot end does NOT reach the compensation-point exit either, which is worth +// knowing before reading the zeros as coverage: at the defaults that needs about +// 45 C, and 40 C is the top of this grid. `test_rd_temperature_response` in +// test_leaf.cpp is what covers it. // // A zero counts for this grid, whose psi_soil values are {0.5, 1, 2, 3, 4, 6}, // and says nothing about the model. What the two failure branches do is checked // by test_collar_solve_refuses_rather_than_guessing in test_leaf.cpp. +// ⚠️ COUNTED PER TEMPERATURE, NOT OVER THE WHOLE GRID, and that is most of the +// value of the split once temperature is an axis: a single total would let points +// move between branches as the leaf warms and still add up. Only the 25 C row +// reproduces the historic 198/24/18/48, and it must, because that block is +// byte-identical to the pre-#41 file. struct KindCount { phylloptim::Leaf::OperatingPointKind kind; int expected; }; +// One row per entry of kLeafTemps, in that order. +struct TempKinds { + double leaf_temp; + int interior, pinned_wet, pinned_dry, shutdown; +}; +// +// ⚠️ AND THE SPLIT MOVES WITH TEMPERATURE IN A SPECIFIC DIRECTION, which is the +// measurement this table records rather than a bookkeeping detail. As the leaf +// warms, DRY-pinned points disappear and WET-pinned ones proliferate: 18 -> 18 -> 3 +// -> 0 dry against 24 -> 24 -> 43 -> 80 wet. A hot leaf assimilates less and +// respires more, so it has less to gain from water and its optimum presses against +// the WET bound instead of the dry one. +// +// The 48 shut-down rows are temperature-INDEPENDENT, and that is the right answer: +// they are the psi_soil = 6 MPa rows, where hydraulics forbid transpiration whatever +// the leaf temperature. +const TempKinds kExpectedKinds[] = { + {15.0, 198, 24, 18, 48}, + {25.0, 198, 24, 18, 48}, + {35.0, 194, 43, 3, 48}, + {40.0, 160, 80, 0, 48}, +}; + int check_operating_kinds(const std::vector &rows) { using Kind = phylloptim::Leaf::OperatingPointKind; - const KindCount expected[] = { - {Kind::Interior, 198}, {Kind::PinnedWet, 24}, - {Kind::PinnedDry, 18}, {Kind::HydraulicShutdown, 48}, - {Kind::Determined, 0}, {Kind::ShadeDeath, 0}, - {Kind::Prescribed, 0}, {Kind::SolverRefused, 0}, - {Kind::NonFiniteGradient, 0}, {Kind::Unsolved, 0}, - }; - int failures = 0; int classified = 0; - for (const KindCount &e : expected) { - int got = 0; - for (const Row &r : rows) { - if (r.kind == e.kind) { - ++got; + for (const TempKinds &e : kExpectedKinds) { + const KindCount expected[] = { + {Kind::Interior, e.interior}, + {Kind::PinnedWet, e.pinned_wet}, + {Kind::PinnedDry, e.pinned_dry}, + {Kind::HydraulicShutdown, e.shutdown}, + {Kind::Determined, 0}, {Kind::ShadeDeath, 0}, + {Kind::Prescribed, 0}, {Kind::SolverRefused, 0}, + {Kind::NonFiniteGradient, 0}, {Kind::Unsolved, 0}, + }; + for (const KindCount &k : expected) { + int got = 0; + for (const Row &r : rows) { + if (r.leaf_temp == e.leaf_temp && r.kind == k.kind) { + ++got; + } + } + classified += got; + if (got != k.expected) { + ++failures; + fprintf(stderr, "FAIL kinds at T=%g: %s got %d, expected %d\n", + e.leaf_temp, + phylloptim::Leaf::operating_point_kind_name(k.kind), got, + k.expected); } - } - classified += got; - if (got != e.expected) { - ++failures; - fprintf(stderr, "FAIL kinds: %s got %d, expected %d\n", - phylloptim::Leaf::operating_point_kind_name(e.kind), got, - e.expected); } } if (classified != static_cast(rows.size())) { @@ -175,19 +234,25 @@ int check_operating_kinds(const std::vector &rows) { rows.size()); } if (failures == 0) { - printf("kinds: %zu points -- 198 interior, 42 pinned (24 wet, 18 dry), " - "48 shutdown\n", - rows.size()); + printf("kinds: %zu points at %zu leaf temperatures\n", rows.size(), + sizeof kExpectedKinds / sizeof kExpectedKinds[0]); + for (const TempKinds &e : kExpectedKinds) { + printf(" T = %4.1f C %3d interior, %2d pinned (%2d wet, %2d dry), " + "%2d shutdown\n", + e.leaf_temp, e.interior, e.pinned_wet + e.pinned_dry, e.pinned_wet, + e.pinned_dry, e.shutdown); + } } return failures == 0 ? 0 : 1; } const char *kHeader = - "psi_soil\tppfd\tvpd\tlayers\tpsi_stem\topt_root_psi\tci\tassim\ttranspiration\t" - "gc\tprofit\te_up\tuptake\n"; + "psi_soil\tppfd\tvpd\tleaf_temp\tlayers\tpsi_stem\topt_root_psi\tci\tassim\t" + "transpiration\tgc\tprofit\te_up\tuptake\n"; void write_row(FILE *f, const Row &r) { - fprintf(f, "%.17g\t%.17g\t%.17g\t%d", r.psi_soil, r.ppfd, r.vpd, r.layers); + fprintf(f, "%.17g\t%.17g\t%.17g\t%.17g\t%d", r.psi_soil, r.ppfd, r.vpd, + r.leaf_temp, r.layers); for (double v : {r.psi_stem, r.opt_root_psi, r.ci, r.assim, r.transpiration, r.gc, r.profit, r.e_up, r.uptake}) { fprintf(f, "\t%.17g", v); @@ -296,12 +361,14 @@ int compare(Tolerance tol) { break; } Row g{}; - // 4 inputs then 9 outputs + // 5 inputs then 9 outputs const int n = sscanf( - line, "%lg\t%lg\t%lg\t%d\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg", - &g.psi_soil, &g.ppfd, &g.vpd, &g.layers, &g.psi_stem, &g.opt_root_psi, &g.ci, - &g.assim, &g.transpiration, &g.gc, &g.profit, &g.e_up, &g.uptake); - if (n != 13) { + line, + "%lg\t%lg\t%lg\t%lg\t%d\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg\t%lg", + &g.psi_soil, &g.ppfd, &g.vpd, &g.leaf_temp, &g.layers, &g.psi_stem, + &g.opt_root_psi, &g.ci, &g.assim, &g.transpiration, &g.gc, &g.profit, + &g.e_up, &g.uptake); + if (n != 14) { fprintf(stderr, "FAIL: row %zu is malformed (%d fields)\n", i, n); ++failures; continue; @@ -345,10 +412,10 @@ int compare(Tolerance tol) { if (!ok) { if (failures < 20) { fprintf(stderr, - "FAIL psi_soil=%g ppfd=%g vpd=%g layers=%d %s: got %.17g, " + "FAIL psi_soil=%g ppfd=%g vpd=%g T=%g layers=%d %s: got %.17g, " "want %.17g (rel %.3g)\n", - r.psi_soil, r.ppfd, r.vpd, r.layers, fd.name, fd.got, fd.want, - rd); + r.psi_soil, r.ppfd, r.vpd, r.leaf_temp, r.layers, fd.name, + fd.got, fd.want, rd); } ++failures; } @@ -366,10 +433,11 @@ int compare(Tolerance tol) { char worst[256] = "none (bit-identical)"; if (worst_rel > 0.0) { snprintf(worst, sizeof worst, - "%.3g at psi_soil=%g ppfd=%g vpd=%g layers=%d %s " + "%.3g at psi_soil=%g ppfd=%g vpd=%g T=%g layers=%d %s " "(got %.17g, want %.17g)", worst_rel, worst_row.psi_soil, worst_row.ppfd, worst_row.vpd, - worst_row.layers, worst_desc, worst_got, worst_want); + worst_row.leaf_temp, worst_row.layers, worst_desc, worst_got, + worst_want); } const bool exact_mode = tol.argmax < 0.0; diff --git a/tests/cpp/test_leaf.cpp b/tests/cpp/test_leaf.cpp index ddfae8c..4cb041c 100644 --- a/tests/cpp/test_leaf.cpp +++ b/tests/cpp/test_leaf.cpp @@ -779,7 +779,7 @@ void test_collar_solve_handles_a_pinned_optimum() { // bit-identical golden run says nothing here. The sequence below alternates kinds // on purpose, so an unwritten tag reads as the step before it. // -// The count check over the whole 288-point grid lives in test_golden.cpp; this is +// The count check over the whole 1152-point grid lives in test_golden.cpp; this is // the other half -- that every path writes, and that the tag comes from the // branch rather than from the numbers. void test_operating_point_kind_is_written_by_every_path() { diff --git a/tests/validate/compare_with_plant.R b/tests/validate/compare_with_plant.R index 067012f..c3ebed9 100644 --- a/tests/validate/compare_with_plant.R +++ b/tests/validate/compare_with_plant.R @@ -101,6 +101,17 @@ psi_soils <- c(0.5, 1.0, 2.0, 3.0, 4.0, 6.0) ppfds <- c(100, 500, 900, 1500) vpds <- c(0.5, 1.0, 2.0, 4.0) layer_counts <- c(1L, 3L, 5L) +# ⚠️ LEAF TEMPERATURE IS AN AXIS NOW (#41), not the fixed 25 C this script used to +# assume, because the golden file it reads has four temperature blocks. Two +# consequences before running anything: +# +# * at 25 C the comparison means what it always meant -- and a difference there is +# a DIFFERENT bug, since #41 is inert at the reference point by construction; +# * at 15 / 35 / 40 C phylloptim and a pre-#41 plant are EXPECTED to differ, +# because R_d's shape changed. `Leaf::rd_tracks_vcmax_` is what makes that arm +# comparable, and it lives on the phylloptim side, so an arm that uses it cannot +# be read out of the golden file -- see the arm table in this file's header. +leaf_temps <- c(15.0, 25.0, 35.0, 40.0) # Fixed drivers and traits, from plant's tests/testthat/test-leaf.r. theta <- 0.000157 @@ -111,7 +122,6 @@ rho <- 608.0 a_bio <- 0.0245 ca <- 40.0 o2 <- 21.0 -tleaf <- 25.0 patm <- 101.3 # Every constructor argument passed explicitly, matching the C++ default @@ -130,7 +140,7 @@ new_leaf <- function() { ) } -solve_one <- function(psi_soil, ppfd, vpd, layers) { +solve_one <- function(psi_soil, ppfd, vpd, layers, leaf_temp) { l <- new_leaf() i <- seq_len(layers) ps <- psi_soil + 0.25 * (i - 1) @@ -142,13 +152,14 @@ solve_one <- function(psi_soil, ppfd, vpd, layers) { PPFD = ppfd, psi_soil = ps, soil_depth = depth, leaf_specific_conductance_max = K_s * theta / h, atm_vpd = vpd, ca = ca, sapwood_volume_per_leaf_area = theta * h, - leaf_temp = tleaf, atm_o2_kpa = o2, atm_kpa = patm + leaf_temp = leaf_temp, atm_o2_kpa = o2, atm_kpa = patm ) l$find_root_collar_psi() cons <- l$soil_consumption_ data.frame( - psi_soil = psi_soil, ppfd = ppfd, vpd = vpd, layers = layers, + psi_soil = psi_soil, ppfd = ppfd, vpd = vpd, leaf_temp = leaf_temp, + layers = layers, psi_stem = l$opt_psi_stem_, opt_root_psi = l$opt_root_psi_, ci = l$ci_, assim = l$assim_colimited_, transpiration = l$transpiration_, gc = l$stom_cond_CO2_, @@ -158,15 +169,15 @@ solve_one <- function(psi_soil, ppfd, vpd, layers) { } grid <- expand.grid(layers = layer_counts, vpd = vpds, ppfd = ppfds, - psi_soil = psi_soils) + psi_soil = psi_soils, leaf_temp = leaf_temps) # expand.grid varies the FIRST column fastest; the C++ loops nest -# psi_soil > ppfd > vpd > layers, with layers innermost. Listing them in -# reverse above therefore reproduces the C++ row order. -grid <- grid[, c("psi_soil", "ppfd", "vpd", "layers")] +# leaf_temp > psi_soil > ppfd > vpd > layers, with layers innermost. Listing them +# in reverse above therefore reproduces the C++ row order. +grid <- grid[, c("psi_soil", "ppfd", "vpd", "leaf_temp", "layers")] cat(sprintf("Running plant's Leaf over %d operating points...\n", nrow(grid))) plant_rows <- do.call(rbind, Map(solve_one, grid$psi_soil, grid$ppfd, - grid$vpd, grid$layers)) + grid$vpd, grid$layers, grid$leaf_temp)) # --- compare ------------------------------------------------------------------ @@ -201,7 +212,7 @@ stopifnot(nrow(golden) == nrow(plant_rows)) # The inputs must line up before comparing outputs, or we would be comparing # different operating points and calling it agreement. -for (key in c("psi_soil", "ppfd", "vpd", "layers")) { +for (key in c("psi_soil", "ppfd", "vpd", "leaf_temp", "layers")) { if (!isTRUE(all.equal(golden[[key]], plant_rows[[key]], tolerance = 0))) { stop("grid mismatch in '", key, "': the R grid is not in the same order as ", "the C++ one, so the comparison would be meaningless") From e70f057d71b89baf1ffbdf9c171a636e7088aada Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Mon, 10 Aug 2026 21:18:55 +1000 Subject: [PATCH 09/13] Revalidate against plant away from 25 C (#41) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⚠️ Pinning leaf temperature at 25 C would have proved nothing: #41 is inert there by construction, so bit-identicality only says the reference point survived. Both new harnesses vary temperature. Three arms over the 1152-point grid, against origin/master: default at 25 C only 0 of 2592 cells differ rd_tracks_vcmax_ = TRUE, all four temps 0 of 10368 cells differ default, all four temps 6018 of 10368 cells differ The middle arm is the result: with the old shape restored, everything else in #41 -- cache key, settable R_d_25, shut-down exit, R API -- is jointly bit-identical to master. A moves +0.05..+3.5% at 15 C, exactly 0 at 25 C, -5.7..-100% at 35 C, -35..-213% at 40 C; no row changed feasibility. plant, TF24 SCM offspring production: BIT-IDENTICAL at plant's defaults (TF24_Environment pins leaf_temp = 25 with PM off, so #41 is inert there), -7.9% at a 30 C driver, /331 at 35 C, and -47.2% with Penman-Monteith on -- where leaf temperature reaches 62 C, +22 K above air, and Tleaf itself moves through the transpiration coupling. plant's leaf/TF24 tests: 486 checks, 0 failures, and its one error is present identically on the control. compare_with_plant.R still does not run; its header blames the wrong thing and PLAN 41 records the real obstacle. Co-Authored-By: Claude Opus 5 (1M context) --- NEWS.md | 65 +++++++++++++++ PLAN.md | 73 ++++++++++++++-- tests/validate/rd_shape_arms.R | 138 +++++++++++++++++++++++++++++++ tests/validate/rd_shape_grid.cpp | 112 +++++++++++++++++++++++++ 4 files changed, 379 insertions(+), 9 deletions(-) create mode 100644 tests/validate/rd_shape_arms.R create mode 100644 tests/validate/rd_shape_grid.cpp diff --git a/NEWS.md b/NEWS.md index 353f68d..92c3c1f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,70 @@ # phylloptim 0.2.1 +## Revalidated against plant, at temperatures other than 25 °C (#41) + +⚠️ **The obvious way to do this was to pin leaf temperature at 25 °C, and it would +have been worthless.** #41 is inert at 25 °C *by construction* — respiration's +reference value is defined there — so a bit-identical result at 25 °C proves the +reference point survived and nothing else. Both harnesses are new and both vary +temperature: `tests/validate/rd_shape_grid.cpp` on this package's grid, and +`tests/validate/rd_shape_arms.R` on plant. + +**Three arms over the 1152-point grid**, against phylloptim at `origin/master`: + +| arm | cells differing | what it isolates | +|---|---|---| +| default, 25 °C only | **0 of 2592** | the control | +| `rd_tracks_vcmax_ = TRUE`, all four temperatures | **0 of 10368** | the shape change alone | +| default, all four temperatures | 6018 of 10368 | the blast radius | + +The middle row is the strong result: with the old shape restored, **everything else +in #41 — the cache key, the settable `R_d_25`, the shut-down exit, the R API — is +jointly bit-identical to master.** That is proved rather than argued, and it is what +the escape hatch was added for. + +Assimilation moves +0.05% to +3.51% at 15 °C, exactly 0 at 25 °C, −5.7% to −100% at +35 °C, and −35% to −213% at 40 °C. **No row changed feasibility** — the 48 shut-down +rows per temperature are the same rows. Of the 864 rows whose A moves, 269 keep their +exact operating point: 144 shut down, and 125 sit pinned to a bound that temperature +does not move, so only their carbon balance changes. + +**On the plant side**, TF24 SCM offspring production (one species, +`max_patch_lifetime = 5`, the setup plant's own regression test uses): + +| plant configuration | master | this branch | change | +|---|---|---|---| +| default (`leaf_temp` = 25, PM off) | 81.857087216483691 | 81.857087216483691 | **bit-identical** | +| `leaf_temp` driver = 30 °C | 24.2830737 | 22.3699929 | −7.9% | +| `leaf_temp` driver = 35 °C | 2.1302e-04 | 6.4472e-07 | ÷331 | +| Penman-Monteith on | 2.2034982 | 1.1638497 | **−47.2%** | + +⚠️ **plant pins 25 °C itself at its defaults**, which is what makes the first row +exact: `TF24_Environment` sets `leaf_temp` as a *constant* extrinsic driver at 25 and +`use_energy_balance` defaults to 0. So a default plant run is unaffected, and the +exposure is entirely in the two configurations that leave 25 °C. + +⚠️ **The Penman-Monteith row is the one to carry forward.** On that path leaf +temperature reaches **62 °C, up to +22 K above air temperature** (measured over PAR +400–2000 × Tair 20–40 × VPD 1–3), so a PM leaf at 25 °C air already sits at 32.9 °C +and loses 23% of its assimilation. `Tleaf` itself moved on 22 of 90 cells, because +the energy balance couples back through transpiration — on that path leaf temperature +is an output, not an input. + +plant needs no source change: it never calls `set_traits`, so the fourteenth argument +is invisible to it, and it binds only `R_d_` of the respiration fields. Its +leaf/TF24 test files give **486 checks, 0 failures** and one error, and that error is +**present identically on the control** — pre-existing on plant develop, not #41. + +**Still not covered, and recorded so the next attempt starts from the real +obstacle**: `compare_with_plant.R`, which compares against plant's own independent +`Leaf`, still does not run. Its header blames the constructor signature; that is no +longer the obstacle. Against plant at 76df7169 both `Leaf()` and `set_physiology()` +work, and what stops it is `root_collar_psi_` versus `opt_root_psi_` — the #25 +rename, which flipped the sign — on top of results deliberately moved by #15, 11a, +11b, #25, #77 and #84. That is issue #64 and it needs a decision about the reference, +not a rename. + + ## The golden grid has a temperature axis: 288 points become 1152 (#41) ⚠️ **The golden file was blind to every temperature response in the model, and had diff --git a/PLAN.md b/PLAN.md index 23bb6a4..986536d 100644 --- a/PLAN.md +++ b/PLAN.md @@ -35,7 +35,7 @@ the user-visible history. | [#34](https://github.com/traitecoevo/phylloptim/issues/34) | 6d | Delete plant's `Leaf` bindings | Unblocked (plant #591 merged, and #33 is done). The hazard-7 payoff, and the only stage that can break plant | | [#38](https://github.com/traitecoevo/phylloptim/issues/38) | 38 | `psi_crit` above the curve's domain fails with an error naming neither | Bounds how far `stem_b` can move in one step; see 11f | | [#40](https://github.com/traitecoevo/phylloptim/issues/40) | 40 | Cross-validate the Medlyn path against `plantecophys` | From #6. Ties to #3, which needs Medlyn first-class | -| [#41](https://github.com/traitecoevo/phylloptim/issues/41) | 41 | `R_d` cannot be set from R: `rd_to_vcmax_ratio_` is unbound | From #6. **74% Rd overstatement** for *Q. ilex* against Sabot's data | +| [#41](https://github.com/traitecoevo/phylloptim/issues/41) | 41 | `R_d`: settable, differentiable, and rising with temperature | **DONE.** From #6. The scale was the smaller half — the SHAPE was peaked and fell above the thermal optimum. Bit-identical at plant's defaults, −47% offspring production on the PM path | | [#49](https://github.com/traitecoevo/phylloptim/issues/49) | 14 | Is `kmax ~ h^-1` defensible? Koçillari et al. 2021 find no height trend | Split out of item 14, which had it filed nowhere | | [#50](https://github.com/traitecoevo/phylloptim/issues/50) | 8 | `H2O_CO2_stom_diff_ratio` is 1.67, the g1 literature uses 1.6 | **2.2% offset** in every reported `g1_eff` | | [#51](https://github.com/traitecoevo/phylloptim/issues/51) | 10c | `kg_to_mol_h2o` and `kg_per_mol_h2o` are not reciprocals | **0.028%**. The bit-identity baseline it was waiting for now exists | @@ -529,15 +529,70 @@ an established external implementation to check against — and #3 needs it first-class. `plantecophys` also solves the coupled system analytically rather than by root-finding, which is worth considering on its own merits. Found doing #6. -## 41. `R_d` cannot be set from R +## 41. `R_d` — DONE, and the shape mattered more than the scale -`rd_to_vcmax_ratio_` became a settable C++ member in #15, but it is **absent from -`inst/RcppR6_classes.yml`** and is not a constructor argument, so from R a fixed -0.015 is imposed. `R_d_` is bound read/write, but every `set_physiology()` recomputes -it. Sabot's data imply ratios of **0.0046–0.0302** — a factor of 6.5 — and for -*Q. ilex* the model uses 0.914 against the data's 0.525, a **74% Rd overstatement** -and a systematic ~4% species-varying bias in A. ⚠️ Item 10b's claim that this -parameter "is now settable" is true of C++ and false from R. +The original complaint: `rd_to_vcmax_ratio_` became a settable C++ member in #15 but +was **absent from `inst/RcppR6_classes.yml`** and not a constructor argument, so from +R a fixed 0.015 was imposed, and `R_d_`, though bound read/write, was recomputed by +every `set_physiology()`. Sabot's data imply ratios of **0.0046–0.0302** — a factor +of 6.5 — and for *Q. ilex* the model used 0.914 against the data's 0.525, a **74% Rd +overstatement** and a systematic ~4% species-varying bias in A. + +All of that is fixed: the temperature cache keys on everything it reads, `R_d_25` is +a trait, and it is differentiable at its default. But the reachable part turned out to +be the smaller half of the problem. + +⚠️ **THE SHAPE WAS WRONG, NOT JUST THE SCALE, AND NO VALUE OF THE RATIO COULD FIX +IT.** `R_d` was `ratio * vcmax_(T)`, so it inherited Vcmax's **peaked** Arrhenius and +therefore **fell** above the thermal optimum, where real dark respiration rises — the +opposite direction, and an order of magnitude out by 50 °C. Replaced with Tjoelker's +declining Q10. A constant Q10 = 2 was implemented first and rejected on measurement +(R_d 4.07 at 40 °C, −73% on A, no operating point at all by 45 °C). + +`rd_tracks_vcmax_` is the way back to the old shape, and it exists because without it +**no published plant result computed under the old shape could be regenerated** — a +reproducibility hole this item created. It is also what makes the revalidation a +controlled A/B rather than an argument. + +**What the A/B says.** Over the 1152-point golden grid +(`tests/validate/rd_shape_grid.cpp`), against phylloptim at `origin/master`: + +| arm | cells differing | verdict | +|---|---|---| +| default, 25 °C only | **0 of 2592** | the control holds | +| `rd_tracks_vcmax_ = TRUE`, all four temperatures | **0 of 10368** | the whole of #41 is the shape and nothing else | +| default, all four temperatures | 6018 of 10368 | the blast radius | + +The second row is the strong one: the cache key, the settable `R_d_25`, the shut-down +exit and the R API are jointly **behaviour-neutral**, proved rather than argued. + +Assimilation moves +0.05 to +3.51% at 15 °C, exactly 0 at 25 °C, −5.7 to −100% at +35 °C and −35 to −213% at 40 °C. **No row changed feasibility** — the 48 shut-down +rows per temperature are the same rows. Of the 864 rows whose A moves, 269 keep their +exact operating point: 144 shut down, and 125 sit pinned to a bound temperature does +not move, so only their carbon balance changes. + +**On the plant side** (`tests/validate/rd_shape_arms.R`), TF24 SCM offspring +production is **bit-identical at plant's defaults** — because `TF24_Environment` pins +`leaf_temp` as a constant 25 °C driver with Penman-Monteith off, so #41 is inert there +by construction — then **−7.9%** at a 30 °C driver, **÷331** at 35 °C, and **−47.2%** +with PM on. The PM row is the one to carry forward: leaf temperature there runs to +**62 °C, up to +22 K above air**, and `Tleaf` itself moves, because the energy balance +couples back through transpiration. + +⚠️ **The golden file was blind to all of this and had been all along** — 288 points at +one temperature, where every reference value is defined. It has a temperature axis +now. Read the developer guide's golden-file section before trusting a bit-identical +run about any temperature response. + +**Still open:** `compare_with_plant.R`, against plant's own independent `Leaf`, does +not run — item 64. The obstacle is not the constructor signature its header blames: +against plant at 76df7169 both `Leaf()` and `set_physiology()` work, and what stops it +is `root_collar_psi_` versus `opt_root_psi_` (the #25 rename, which flipped the sign) +on top of results deliberately moved by #15, 11a, 11b, #25, #77 and #84. + +⚠️ Item 10b's claim that this parameter "is now settable" was true of C++ and false +from R; it is now true of both. ## 14. Naming, home, publication diff --git a/tests/validate/rd_shape_arms.R b/tests/validate/rd_shape_arms.R new file mode 100644 index 0000000..6fee10b --- /dev/null +++ b/tests/validate/rd_shape_arms.R @@ -0,0 +1,138 @@ +# The #41 respiration-shape revalidation, ON THE PLANT SIDE. +# +# Rscript tests/validate/rd_shape_arms.R +# +# The companion to rd_shape_grid.cpp, which does the same A/B on this package's own +# grid. This one runs plant, because plant is the consumer and an integrated +# demographic output is not predictable from a per-leaf one. +# +# ⚠️ DO NOT RUN THIS PINNED AT 25 C AND CALL IT REVALIDATED, which was the obvious +# temptation and is worthless. #41 is inert at 25 C BY CONSTRUCTION -- the +# respiration reference value is defined there -- so a bit-identical result at 25 C +# proves only that the reference point survived, which is a control and not a +# validation. The information is at the temperatures plant actually reaches. +# +# ⚠️ AND PLANT ITSELF PINS 25 C AT ITS DEFAULTS, which is the fact that decides how +# to read all of this. `TF24_Environment` sets `leaf_temp` as a CONSTANT extrinsic +# driver at 25, and `use_energy_balance` defaults to 0 (Tleaf = Tair). So at plant's +# default configuration #41 changes nothing, and that is provable rather than +# observed. The exposure is in the two configurations that leave 25 C: a +# non-default `leaf_temp` driver, and the Penman-Monteith path (plant #523). +# +# --- what was measured, 2026-08-10 -------------------------------------------- +# +# TF24 SCM offspring production, one species, max_patch_lifetime = 5: +# +# plant configuration phylloptim master this branch change +# default (leaf_temp = 25, PM off) 81.857087216483691 81.857087216483691 BIT-IDENTICAL +# leaf_temp driver = 30 C 24.283073719078399 22.369992929645893 -7.9% +# leaf_temp driver = 35 C 0.00021301630930330433 6.4471696967520308e-07 -99.7% (/331) +# Penman-Monteith energy balance on 2.2034981948510728 1.1638497249192270 -47.2% +# +# The PM row is the one to carry forward: it is where plant is heading, and #41 +# halves offspring production there. The 35 C row is a factor of 331, but on a +# population already four orders below replacement, so it is a large change to a +# number that was already saying "extinct". +# +# Leaf temperature on the PM path, over PAR {400,1000,2000} x Tair {20..40} x +# VPD {1,2,3}: Tleaf runs 19.1 to 62.0 C, i.e. up to +22 K ABOVE air temperature. +# That is why the PM arm moves so much more than its air temperature suggests -- +# a PM leaf at Tair 25 sits at 32.9 C, and mean A there falls 23%. +# +# ⚠️ On the PM path `Tleaf` ITSELF moved, on 22 of 90 cells. The energy balance +# couples to transpiration, so a change in R_d feeds back into leaf temperature +# rather than only into carbon. Do not treat leaf temperature as an input on that +# path. +# +# --- how to build the two arms ------------------------------------------------ +# +# Four installs: phylloptim twice and plant twice, because plant compiles +# phylloptim's headers in. ⚠️ `R_LIBS` FALLS BACK TO THE SITE LIBRARY SILENTLY if +# the intended one is not ready, which happened once while writing this and +# produced a plausible file describing the wrong package -- hence the hard check +# below, and print find.package() in anything you add. +# +# SP=/tmp/rd41; W=$(git rev-parse --show-toplevel) +# SITE=$(Rscript -e 'cat(.Library.site[[1]])') +# mkdir -p $SP/{lib-pm,lib-branch,lib-plant-master,lib-plant-branch} +# git -C $W archive origin/master | tar -x -C $SP/pm-src # mkdir first +# R_LIBS=$SITE R CMD INSTALL --no-docs -l $SP/lib-pm $SP/pm-src +# R_LIBS=$SITE R CMD INSTALL --no-docs -l $SP/lib-branch $W +# # plant, twice, from a CLEAN source copy each time -- a stale src/*.o is a +# # segfault that looks like a real bug (and would silently be the other arm) +# git -C ../plant archive --prefix=plant/ | tar -x -C $SP +# R_LIBS="$SP/lib-pm:$SITE" R CMD INSTALL --no-docs -l $SP/lib-plant-master $SP/plant +# # ...fresh copy, then... +# R_LIBS="$SP/lib-branch:$SITE" R CMD INSTALL --no-docs -l $SP/lib-plant-branch $SP/plant2 +# +# then run this script once per arm with R_LIBS set to that arm and EXPECT_LIB=$SP. +# +# plant needs no source change for this: it never calls `set_traits` (so the +# fourteenth argument is invisible to it) and binds only `R_d_` of the respiration +# fields. Checked against plant's inst/RcppR6_classes.yml. +# +# --- what this does NOT cover ------------------------------------------------- +# +# `compare_with_plant.R` compares against plant's OWN Leaf -- an independent +# implementation -- which is a stronger check than either arm here, and it still +# does not run. Its header blamed the constructor signature; that is no longer the +# obstacle. Against plant at 76df7169 the `Leaf()` and `set_physiology()` calls +# both work, and what actually stops it is that the reference has +# `root_collar_psi_` where this package has `opt_root_psi_` -- the #25 rename, +# which flipped the sign -- on top of results deliberately moved by #15, 11a, 11b, +# #25, #77 and #84. Reviving it is issue #64 and needs a decision about the +# reference, not a rename. Recorded here so the next attempt starts from the real +# obstacle. +suppressMessages(library(plant)) + +# ⚠️ HARD-FAIL ON THE WRONG LIBRARY, for the reason in the header. A warning would +# not do: every number below is plausible for either arm. +want <- Sys.getenv("EXPECT_LIB") +if (!nzchar(want)) { + stop("set EXPECT_LIB to the directory both packages must resolve inside") +} +for (pkg in c("plant", "phylloptim")) { + if (!startsWith(normalizePath(find.package(pkg)), normalizePath(want))) { + stop(pkg, " resolved outside ", want, ": ", find.package(pkg)) + } +} +cat("plant: ", find.package("plant"), "\n") +cat("phylloptim:", find.package("phylloptim"), "\n\n") + +# One SCM run. The setup is test-strategy-tf24.R's own regression case, so the +# default arm is comparable with a number plant already asserts. +offspring <- function(leaf_temp = NULL, energy_balance = FALSE) { + p0 <- scm_base_parameters("TF24") + p0$max_patch_lifetime <- 5 + p1 <- add_strategies(p0, trait_matrix(c(0.0825, 5), c("lma", "hmat")), + hyperpar = TF24_hyperpar, birth_rate = list(20)) + if (energy_balance) { + # ⚠️ THE FLAG LIVES IN `$pars`, and assigning it at the strategy's top level + # is accepted and silently ignored: `p1$strategies[[1]]$use_energy_balance <- + # 1` adds a list element nothing reads, and the run comes back EXACTLY equal + # to the default arm -- which reads as "PM changes nothing" rather than as a + # broken switch. Asserted rather than trusted. + st <- p1$strategies[[1]] + st$pars$use_energy_balance <- 1.0 + p1$strategies[[1]] <- st + stopifnot(p1$strategies[[1]]$pars$use_energy_balance == 1.0) + } + env <- Environment("TF24") + if (!is.null(leaf_temp)) { + env$extrinsic_drivers_set_constant("leaf_temp", leaf_temp) + } + run_scm(p1, env, Control())$offspring_production +} + +cases <- list( + list(label = "default (leaf_temp driver = 25, PM off)", temp = NULL, pm = FALSE), + list(label = "leaf_temp driver = 30", temp = 30, pm = FALSE), + list(label = "leaf_temp driver = 35", temp = 35, pm = FALSE), + list(label = "Penman-Monteith energy balance on", temp = NULL, pm = TRUE) +) +for (cs in cases) { + v <- offspring(cs$temp, cs$pm) + # %.17g, so the two arms can be compared bit-for-bit rather than to the 2e-2 + # the plant test uses -- the point of the default arm is exact equality. + cat(sprintf("%-40s %s\n", cs$label, paste(sprintf("%.17g", v), collapse = " "))) +} diff --git a/tests/validate/rd_shape_grid.cpp b/tests/validate/rd_shape_grid.cpp new file mode 100644 index 0000000..7b8f0de --- /dev/null +++ b/tests/validate/rd_shape_grid.cpp @@ -0,0 +1,112 @@ +// The #41 respiration-shape A/B, on this package's own grid. +// +// Three arms over the 1152 operating points of tests/cpp/golden/, differing only +// in which model computes them. It exists because the golden file can only say +// "something moved": this says WHICH of the four #41 commits moved it, by holding +// the shape fixed and letting everything else vary. +// +// arm model expectation +// master phylloptim at origin/master the reference +// branch this branch, default (declining Q10) moves off 25 C +// branch_old this branch, rd_tracks_vcmax_ = true bit-identical to master +// +// The third arm is the point. If it is bit-identical then the whole of #41 -- +// the cache key, the settable R_d_25, the shut-down exit, the R API -- is +// behaviour-neutral, and every difference in the second arm is the respiration +// shape and nothing else. Measured: 0 of 10368 cells differ. See PLAN item 41. +// +// ⚠️ ONE TREE, THREE BINARIES, as hazard 5 requires of any A/B here. The master +// arm is built from master's HEADERS against this file, not from master's own +// test_golden.cpp -- master's grid is 288 points at 25 C and would answer a +// different question. +// +// W=$(git rev-parse --show-toplevel) +// mkdir -p /tmp/ab && cd /tmp/ab +// cp $W/tests/cpp/root_network.hpp . +// git -C $W archive origin/master inst/include | tar -x --strip-components=2 \ +// -C master_inc # mkdir it first +// ODELIA=$(Rscript -e 'cat(system.file("include", package="odelia"))') +// BH=$(Rscript -e 'cat(system.file("include", package="BH"))') +// for arm in master branch branch_old; do +// case $arm in +// master) INC=master_inc; DEF="" ;; +// branch) INC=$W/inst/include; DEF="" ;; +// branch_old) INC=$W/inst/include; DEF="-DOLD_SHAPE" ;; +// esac +// c++ -std=c++20 -O2 -I. -I$INC -isystem $ODELIA -isystem $BH $DEF \ +// $W/tests/validate/rd_shape_grid.cpp -o grid_$arm +// ./grid_$arm > out_$arm.tsv +// done +// +// Then diff the TSVs. They are written with %.17g in the golden file's own column +// order, so `cmp` is a valid first pass and a per-field relative comparison is the +// second. ⚠️ Do NOT read them back with R's `read.delim` and compare as doubles +// without going through tests/validate/tsv_to_hex.c: R's decimal parser is not +// correctly rounded and perturbs about 18% of full-precision values, which is the +// mistake decision 1 in PLAN.md records. +// +// Not built by `make` or by CMake, and deliberately so: it needs two versions of +// the package at once, which no build in this repo can express. +#include + +#include "root_network.hpp" + +#include +#include +#include + +int main() { + // The golden grid's fixed drivers and axes, from tests/cpp/test_golden.cpp. + const double kTheta = 0.000157, kKs = 1.0, kH = 5.0, kAreaLeaf = 0.05; + const double kCa = 40.0, kO2 = 21.0, kPatm = 101.3; + const double temps[] = {15.0, 25.0, 35.0, 40.0}; + const double psi_soils[] = {0.5, 1.0, 2.0, 3.0, 4.0, 6.0}; + const double ppfds[] = {100.0, 500.0, 900.0, 1500.0}; + const double vpds[] = {0.5, 1.0, 2.0, 4.0}; + const int layer_counts[] = {1, 3, 5}; + + printf("psi_soil\tppfd\tvpd\tleaf_temp\tlayers\tpsi_stem\topt_root_psi\tci\t" + "assim\ttranspiration\tgc\tprofit\te_up\tuptake\n"); + for (double t : temps) { + for (double p : psi_soils) { + for (double q : ppfds) { + for (double v : vpds) { + for (int n : layer_counts) { + phylloptim::Leaf l; + l.setup_transpiration(100); + l.setup_root_vulnerability(100); +#ifdef OLD_SHAPE + // ⚠️ The whole reason this arm exists. Absent on master, where the + // shape is unconditional -- so `-DOLD_SHAPE` must never be combined + // with master's headers, and the compiler will say so. + l.rd_tracks_vcmax_ = true; +#endif + std::vector ps(n), depth(n), root(n); + for (int i = 0; i < n; ++i) { + ps[i] = p + 0.25 * i; + depth[i] = 1.0 * (i + 1); + root[i] = 1.0 / n / kAreaLeaf; + } + l.set_physiology(fixture::root_network(root, depth), q, ps, depth, + kKs * kTheta / kH, v, kCa, t, kO2, kPatm); + l.find_root_collar_psi(); + double uptake = 0.0; + for (double s : l.soil_consumption_) { + if (std::isfinite(s)) { + uptake += s; + } + } + printf("%.17g\t%.17g\t%.17g\t%.17g\t%d", p, q, v, t, n); + for (double x : {l.opt_psi_stem_, l.opt_root_psi_, l.ci_, + l.assim_colimited_, l.transpiration_, + l.stom_cond_CO2_, l.profit_, l.E_up_, uptake}) { + printf("\t%.17g", x); + } + printf("\n"); + } + } + } + } + } + return 0; +} From e714703cb572d45e54524004da849ab4dc2ba997 Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Mon, 10 Aug 2026 21:34:14 +1000 Subject: [PATCH 10/13] The recorded gradients need their own tolerance (#41) Linux CI: `dA/dR_d_25` at interior-1layer disagrees by 1.3e-03 relative, against 1.3e-04 for every gradient column that was there before, so the tolerance borrowed from the solved-output baseline (1e-03) failed. Not a regression, and the mechanism is exact. A gradient here is a finite difference, so it carries the solve's ~1e-9 floor DIVIDED BY THE STEP, and the step is relative -- so the smallest-magnitude parameter sets the tolerance for the whole file. R_d_25 is 1.44 where vcmax_25 is 96: a 67x smaller absolute step. The arithmetic closes at 1.3e-03 x 0.2487 x 2h = 9.3e-10, the floor itself, and a step sweep agrees (at step 1e-7 the R_d_25 column has moved 1.3% and vcmax_25 0.2%). gradient_golden_tolerance() is 5e-03, 3.8x the one observation there is. Verified by forcing the tolerant branch that macOS never takes: the CI disagreement passes, the old 1e-03 fails it, and a real 5% regression still fails. Also corrects three stale cross-platform figures found while reading the CI summary line: test_golden.cpp's header carried the pre-11a pair with a compiler split 11a removed, and the guide's profit row said 1.82e-07 where CI now reports 2.14e-09. Co-Authored-By: Claude Opus 5 (1M context) --- .claude/CLAUDE.md | 35 +++++++++++++++++++++------- tests/cpp/test_golden.cpp | 18 ++++++++++---- tests/testthat/helper-golden.R | 28 ++++++++++++++++++++-- tests/testthat/test-gradient-batch.R | 22 +++++++++++------ tools/gradient_golden.R | 12 ++++++---- 5 files changed, 90 insertions(+), 25 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index bc8c5c9..2e9f8f4 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -88,7 +88,10 @@ tests/testthat/gradient_golden.tsv on that platform only, like tests/cpp/golden/ -- these are derivatives of argmax-evaluated outputs, so they inherit its sqrt-amplified class and - disagree cross-platform by up to 1.3e-4 + disagree cross-platform by up to 1.3e-3 -- ten + times the solved outputs, because a finite + difference divides the solver floor by the step + and `R_d_25`'s step is the smallest here tests/validate/ R scripts comparing against plant (needs R) CMakeLists.txt the no-R build: C++ and Python consumers, and the thing that makes "does not need R" runnable @@ -348,10 +351,21 @@ magnitude apart: | field | gcc | clang | why | |---|---|---|---| -| `profit` | **1.82e-07** | **1.82e-07** | it is the maximum itself — well-conditioned | +| `profit` | **2.14e-09** | **2.14e-09** | it is the maximum itself — well-conditioned | | the other eight | **1.4e-04** | **1.4e-04** | evaluated at the **argmax** — sqrt-amplified | -**These figures changed when PLAN 11a replaced the collar solver, and how they +Read off CI's summary line on the 1152-point grid, 7702 of 10368 values differing, +against tolerances of 1e-05 and 5e-03. + +⚠️ **The `profit` row said 1.82e-07 until #41 and that was stale, not superseded by +the bigger grid.** A grid can only move a *maximum* upward, and the 25 °C block is +byte-identical — so the improvement is a change to the model on `master` since the +figure was recorded (#77 and #84 are the candidates), and it is NOT attributed here +because doing so needs a cross-platform run of master, which no macOS box can give +you. Take the lesson rather than the number: **this table is a CI reading, and it +goes stale silently because nothing asserts it.** Read the summary line. + +**These figures also changed when PLAN 11a replaced the collar solver, and how they changed is informative.** They were `profit` 1.85e-06 / 5.87e-07 and the other eight 5.53e-04 / 2.73e-04. Two things to take from the move: @@ -361,11 +375,16 @@ eight 5.53e-04 / 2.73e-04. Two things to take from the move: left is libm's `exp`/`pow`, which is a property of the platform and not of the compiler. So do not expect a compiler-dependent column here any more — and if one reappears, something has reintroduced a discrete decision into the solve. -- **The sqrt story now fits better than it did.** `sqrt(1.82e-07)` ≈ 4.3e-04 - against the 1.4e-04 observed, where before it was `sqrt(1.85e-06)` ≈ 1.4e-03 - against 5.5e-04. Same order in both cases, but the residual factor shrank, which - is what you would expect once the argmax stopped carrying an extra `GSS_tol_abs` - of arbitrary displacement on top of the flat-maximum amplification. +- **The sqrt story fits, but no longer tightly.** At 11a it was `sqrt(1.85e-06)` ≈ + 1.4e-03 against 5.5e-04 observed, then `sqrt(1.82e-07)` ≈ 4.3e-04 against + 1.4e-04 — same order, with the residual factor shrinking as expected once the + argmax stopped carrying an extra `GSS_tol_abs` of arbitrary displacement. It does + NOT survive the current pair: `sqrt(2.14e-09)` ≈ 4.6e-05 against 1.4e-04 + observed, which is three times the other way. ⚠️ Do not read that as a broken + identity — it never was one. The two column maxima fall at *different* operating + points, and the argmax column now has 864 hot rows the profit column's worst case + is not among. `sqrt(worst profit)` is a sanity check on the mechanism, not a + prediction of `worst argmax`. The maximum is *flat*: curvature measured directly at the two worst points gives k ≈ 1.0 and 0.9 in `profit ≈ p* − k(psi_stem−x*)²`. For a flat maximum an error diff --git a/tests/cpp/test_golden.cpp b/tests/cpp/test_golden.cpp index 594eed3..c3d8fed 100644 --- a/tests/cpp/test_golden.cpp +++ b/tests/cpp/test_golden.cpp @@ -498,14 +498,24 @@ int compare(Tolerance tol) { // platform is NOT the fix -- it just moves the failure to the first one. // // The interesting part is the SIZE of the disagreement, because it is not one -// number. Measured over the full grid on Linux, the nine reported fields split -// into two classes three orders of magnitude apart: +// number. Read off this program's own summary line on Linux CI over the 1152-point +// grid, the nine reported fields split into two classes five orders of magnitude +// apart, and gcc and clang now agree exactly: // // gcc clang -// profit 1.85e-06 5.87e-07 +// profit 2.14e-09 2.14e-09 // psi_stem, collar, ci, assim, // transpiration, gc, e_up, -// uptake 5.53e-04 2.73e-04 +// uptake 1.4e-04 1.4e-04 +// +// ⚠️ THOSE NUMBERS READ 1.85e-06 / 5.87e-07 AND 5.53e-04 / 2.73e-04 UNTIL #41 -- +// two generations stale, and still carrying a gcc-versus-clang split that PLAN 11a +// removed (it was which way a golden-section comparison fell; what is left is libm, +// a property of the platform and not the compiler). Nothing asserts this comment, +// so it rots in silence. **If you need a magnitude, read the summary line above the +// FAIL lines, not this block and not the FAIL lines** -- the truncated failure list +// is biased toward whichever rows come first, which is how the figure in the +// developer guide came to be wrong twice. // // That split is structural, not luck. `find_root_collar_psi` maximises profit // over the collar potential, and the maximum is FLAT: curvature k measured diff --git a/tests/testthat/helper-golden.R b/tests/testthat/helper-golden.R index de1e96b..204fb8b 100644 --- a/tests/testthat/helper-golden.R +++ b/tests/testthat/helper-golden.R @@ -39,15 +39,39 @@ golden_tolerance <- function(field) { if (identical(field, "profit")) 1.0e-5 else 1.0e-3 } +# ⚠️ THE RECORDED GRADIENTS NEED THEIR OWN, LOOSER TOLERANCE, and borrowing the one +# above was wrong -- it just happened not to fail until #41 added a column. +# +# A gradient here is a FINITE DIFFERENCE of the solve, so cross-platform it carries +# the solve's own ~1e-9 floor DIVIDED BY THE STEP. The step is RELATIVE, so the +# amplification is set by the differentiated parameter's own magnitude, and the +# smallest parameter in the file decides the tolerance for all of it. +# +# Measured on Linux CI: `dA/dR_d_25` at interior-1layer disagrees by 1.3e-03 +# relative, against 1.3e-04 for every column that was here before. `R_d_25` is 1.44 +# where `vcmax_25` is 96 -- a 67x smaller absolute step at the same relative one -- +# and the arithmetic closes: 1.3e-03 x 0.2487 x 2h = 9.3e-10, i.e. the floor itself. +# +# Confirmed independently by the step sweep: at `step = 1e-7` the `R_d_25` column has +# already moved 1.3% while `vcmax_25` has moved 0.2%. That column goes +# noise-dominated first, and it is the one that sets this number. +# +# 5e-03 leaves ~4x headroom over the one observation there is. It cannot hide a real +# change: #41's own reallocation moved these cells by 16% to 250%, two orders above +# this. ⚠️ It IS one CI observation, so read the worst-difference line the test +# prints on every run rather than assuming the headroom is still there. +gradient_golden_tolerance <- function() 5.0e-3 + # expect_identical where it can hold, expect_equal with the measured per-field # tolerance where it cannot. Wrapped in one place so no individual test has to # decide, and so the reason lives next to the policy rather than at every call. -expect_golden <- function(actual, expected_hex, field, label) { +expect_golden <- function(actual, expected_hex, field, label, + tolerance = golden_tolerance(field)) { expected <- as.numeric(expected_hex) if (golden_bit_exact_platform()) { expect_identical(actual, expected, label = paste(label, field)) } else { - expect_equal(actual, expected, tolerance = golden_tolerance(field), + expect_equal(actual, expected, tolerance = tolerance, label = paste(label, field)) } } diff --git a/tests/testthat/test-gradient-batch.R b/tests/testthat/test-gradient-batch.R index 795b82a..b521a19 100644 --- a/tests/testthat/test-gradient-batch.R +++ b/tests/testthat/test-gradient-batch.R @@ -220,12 +220,19 @@ test_that("the recorded gradients have not moved", { # test-golden.R's first version made. libm's exp/pow are not bit-reproducible # between glibc on x86-64 and Apple's libm on arm64. # - # THE TOLERANCE IS NOT A GUESS AND NOT NEW. These are derivatives of outputs - # evaluated at the ARGMAX of a flat maximum, so they belong to the golden file's - # own sqrt-amplified class -- and `golden_tolerance()` is that policy, reused - # here rather than restated. Measured worst relative disagreement on Linux is - # 1.3e-4, against the golden file's 1.4e-4 for the same class: a central - # difference cancels the systematic part of a libm difference but not all of it. + # ⚠️ THIS FILE USED `golden_tolerance()` AND THAT WAS WRONG -- borrowed from the + # solved-output baseline, where it happened not to fail until #41 added a column. + # A gradient here is a FINITE DIFFERENCE, so it carries the solve's ~1e-9 floor + # DIVIDED BY THE STEP, and since the step is relative the amplification is set by + # the differentiated parameter's own magnitude. `R_d_25` is 1.44 where `vcmax_25` + # is 96, so it takes a 67x smaller absolute step and disagrees 10x more -- + # 1.3e-03 on Linux against 1.3e-04 for every column that was here before. + # `gradient_golden_tolerance()` is that measurement, with the arithmetic. + # + # The pre-existing columns were, and remain, in the golden file's own + # sqrt-amplified class: derivatives of outputs evaluated at the ARGMAX of a flat + # maximum, where a central difference cancels the systematic part of a libm + # difference but not all of it. # # ⚠️ Read the SUMMARY LINE below for a magnitude, never the FAIL lines. The # figures in this package's guide were wrong twice because a truncated failure @@ -242,7 +249,8 @@ test_that("the recorded gradients have not moved", { for (out in c("A", "gc", "psi_stem", "collar")) { got <- g$gradient[1, rows$par[[i]], out] expect_golden(got, rows[[out]][[i]], out, - paste(nm, rows$par[[i]])) + paste(nm, rows$par[[i]]), + tolerance = gradient_golden_tolerance()) ref <- as.numeric(rows[[out]][[i]]) if (ref != 0) { worst <- max(worst, abs(got - ref) / abs(ref)) diff --git a/tools/gradient_golden.R b/tools/gradient_golden.R index 47ab662..77ac6b1 100644 --- a/tools/gradient_golden.R +++ b/tools/gradient_golden.R @@ -31,10 +31,14 @@ # on Linux would just move the failure to the platform the file came from. # # These are derivatives of outputs evaluated at the ARGMAX of a flat maximum, so -# they inherit that file's sqrt-amplified class: measured worst cross-platform -# disagreement 1.3e-4, against 1.4e-4 for the same class of solved outputs. A -# central difference cancels the systematic part of a libm difference, not all of -# it. +# they inherit that file's sqrt-amplified class -- and, being finite differences, +# one amplification more. Measured worst cross-platform disagreement 1.3e-3, +# against 1.4e-4 for the solved outputs themselves. A central difference cancels +# the systematic part of a libm difference, not all of it, and what is left is +# divided by the step: the smallest-magnitude parameter in the file therefore sets +# the tolerance for all of it, which since #41 is `R_d_25` at 1.44 rather than +# `vcmax_25` at 96. `gradient_golden_tolerance()` in tests/testthat/helper-golden.R +# carries the arithmetic. suppressMessages(library(phylloptim)) # The golden grid's drivers, so every row here is an operating point the rest of From c0746477a380efb9430aaeab0b7e57e79b8163da Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Tue, 11 Aug 2026 06:52:27 +1000 Subject: [PATCH 11/13] R_d_25 as a plain trait, with no fallbacks (#41) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review: back compatibility comes from using the same VALUES, not from infrastructure, so the special-casing goes. R_d_25 now defaults to 1.44 -- 0.015 * 96, bit-for-bit the double the old vcmax-derived form gave -- with no NaN sentinel, no rd_to_vcmax_ratio_ (deleted, C++ and R bindings), and no rd_tracks_vcmax_ escape hatch. An unset or negative value fails instead of deriving something. The enumeration is reordered properly: R_d_25 is the fourteenth trait, in set_traits' own argument order, with kmax and resistance after it. Every index in gradient.hpp has a name, so nothing indexes theta with a bare integer, and the R side needs no set difference to reconcile. ⚠️ Respiration no longer follows vcmax_25 -- the point of a trait, and the one exception to "same defaults, same results". plant's TF24 SCM offspring production is BIT-IDENTICAL at its defaults (81.857087216483691), and moves when vcmax_25 varies: 0.40692 -> 0.34336 at 60, 73.703 -> 92.026 at 150. That coupling belongs in the caller's parameterisation, where plant already derives its other parameters. Golden grid cut to two temperatures, 25 and 40 C, so 1152 rows become 576; the 25 C block stays byte-identical. Comments cut throughout, the two single-use validate harnesses removed, and their measurements kept in PLAN 41. 486 C++ checks, golden bit-identical, 933 R checks, ctest 2/2, consumer exit 0, R CMD check 1 pre-existing NOTE. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/cpp-tests.yml | 19 +- NEWS.md | 344 ++++-------- PLAN.md | 72 +-- R/RcppExports.R | 16 - R/RcppR6.R | 16 +- R/gradient-batch.R | 26 +- R/gradient.R | 122 +---- R/leaf-model.R | 39 +- inst/RcppR6_classes.yml | 58 +-- inst/include/phylloptim/gradient.hpp | 55 +- inst/include/phylloptim/leaf_model.hpp | 184 ++----- man/leaf_gradient.Rd | 14 +- man/leaf_traits.Rd | 13 +- src/RcppExports.cpp | 48 -- src/RcppR6.cpp | 18 - tests/cpp/bench_gradient.cpp | 8 +- tests/cpp/golden/operating_points.tsv | 576 --------------------- tests/cpp/test_golden.cpp | 63 +-- tests/cpp/test_leaf.cpp | 216 ++------ tests/testthat/test-gradient-batch.R | 47 +- tests/testthat/test-gradient.R | 36 +- tests/testthat/test-surface.R | 34 +- tests/testthat/test-temperature-response.R | 63 +-- tests/validate/rd_shape_arms.R | 138 ----- tests/validate/rd_shape_grid.cpp | 112 ---- 25 files changed, 372 insertions(+), 1965 deletions(-) delete mode 100644 tests/validate/rd_shape_arms.R delete mode 100644 tests/validate/rd_shape_grid.cpp diff --git a/.github/workflows/cpp-tests.yml b/.github/workflows/cpp-tests.yml index 931bd9c..7ce47d7 100644 --- a/.github/workflows/cpp-tests.yml +++ b/.github/workflows/cpp-tests.yml @@ -188,16 +188,14 @@ jobs: d.PPFD = 900; d.psi_soil = {2.0}; d.soil_depth = soil_depth; d.atm_vpd = 2.0; d.ca = 40.0; d.leaf_temp = 25.0; d.atm_o2_kpa = 21.0; d.atm_kpa = 101.3; - // ⚠️ ALL n_pars ELEMENTS, WRITTEN OUT. A short initialiser compiles - // and zero-fills the rest, so when #41 appended R_d_25 this list - // silently supplied 0.0 for it -- a leaf with no respiration -- and - // the only symptom was the arbitrated gradient below. The last entry - // is the RESOLVED reference value: theta must never carry - // set_traits' NaN sentinel, because a NaN is not differentiable. + // ⚠️ ALL n_pars ELEMENTS, WRITTEN OUT: a short initialiser compiles + // and zero-fills the rest, so adding a parameter would silently pass + // 0.0 for it here. The traits in set_traits' order, then the two + // non-traits. double theta[phylloptim::gradient::n_pars] = { 96.0, 2.680147, 3.898245, 5.870283, 2.680147, 3.898245, - 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, - 1.0 * 0.000157 / 5.0, 0.0, 0.015 * 96.0}; + 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, 1.44, + 1.0 * 0.000157 / 5.0, 0.0}; const int pars[1] = {0}; // vcmax_25 const std::vector obs{d, d}; const std::vector g = @@ -213,11 +211,6 @@ jobs: } // The R layer's arbitrated reference for this operating point, loosely // compared for the same reason profit is below. - // - // ⚠️ This read 0.0172086 until #41. That was the TOTAL derivative, with - // respiration following vcmax_25; with R_d_25 a parameter of its own - // this is the PARTIAL at fixed respiration, and the difference is - // rd_to_vcmax_ratio_ * dA/dR_d_25. It is not a change in the model. if (std::fabs(g[0].grad[0] - 0.0209349) > 1e-5) { return 1; } diff --git a/NEWS.md b/NEWS.md index 92c3c1f..919a946 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,248 +1,54 @@ # phylloptim 0.2.1 -## Revalidated against plant, at temperatures other than 25 °C (#41) +## `R_d_25` is a trait, and respiration rises with temperature (#41) -⚠️ **The obvious way to do this was to pin leaf temperature at 25 °C, and it would -have been worthless.** #41 is inert at 25 °C *by construction* — respiration's -reference value is defined there — so a bit-identical result at 25 °C proves the -reference point survived and nothing else. Both harnesses are new and both vary -temperature: `tests/validate/rd_shape_grid.cpp` on this package's grid, and -`tests/validate/rd_shape_arms.R` on plant. +Dark respiration was `rd_to_vcmax_ratio_ * vcmax_(T)`: a fixed fraction of Vcmax, +unreachable from R, and — because it inherited Vcmax's **peaked** Arrhenius — it +**fell** above the thermal optimum, where real dark respiration rises. No value of +the fraction repairs a function of the wrong shape. -**Three arms over the 1152-point grid**, against phylloptim at `origin/master`: +Now `R_d_25` is a `leaf_traits()` trait like any other, and the response is +Tjoelker's declining Q10: -| arm | cells differing | what it isolates | -|---|---|---| -| default, 25 °C only | **0 of 2592** | the control | -| `rd_tracks_vcmax_ = TRUE`, all four temperatures | **0 of 10368** | the shape change alone | -| default, all four temperatures | 6018 of 10368 | the blast radius | +``` +Q10(T) = rd_q10_intercept_ - rd_q10_slope_ * (T + 25) / 2 3.09, 0.0430 +R_d(T) = R_d_25 * Q10(T)^((T - 25) / 10) +``` -The middle row is the strong result: with the old shape restored, **everything else -in #41 — the cache key, the settable `R_d_25`, the shut-down exit, the R API — is -jointly bit-identical to master.** That is proved rather than argued, and it is what -the escape hatch was added for. +The Q10 is evaluated at the mean of T and the reference, which is the form the +land-surface literature implements. Set the slope to zero and the intercept is a +constant Q10, for anyone who wants the conventional form; a constant Q10 of 2 was +tried first and measured too aggressive (R_d 2.8× its 25 °C value over 15 K, −73% on +assimilation at 40 °C, no operating point at all by 45 °C). -Assimilation moves +0.05% to +3.51% at 15 °C, exactly 0 at 25 °C, −5.7% to −100% at -35 °C, and −35% to −213% at 40 °C. **No row changed feasibility** — the 48 shut-down -rows per temperature are the same rows. Of the 864 rows whose A moves, 269 keep their -exact operating point: 144 shut down, and 125 sit pinned to a bound that temperature -does not move, so only their carbon balance changes. +**There is no fallback and no sentinel.** `R_d_25` defaults to **1.44** — which is +`0.015 * 96`, the value the old derivation gave at the default `vcmax_25`, and the +same double — so a caller who does not touch it gets exactly what they got before. +An unset or negative value fails rather than deriving something. -**On the plant side**, TF24 SCM offspring production (one species, -`max_patch_lifetime = 5`, the setup plant's own regression test uses): +⚠️ **RESPIRATION NO LONGER FOLLOWS `vcmax_25`.** That is the point of making it a +trait, and it is the one place "same defaults ⇒ same results" has an exception: +a run that *varies* `vcmax_25` used to get proportionally more or less respiration +and now does not. Measured on plant's TF24 SCM, offspring production: -| plant configuration | master | this branch | change | -|---|---|---|---| -| default (`leaf_temp` = 25, PM off) | 81.857087216483691 | 81.857087216483691 | **bit-identical** | -| `leaf_temp` driver = 30 °C | 24.2830737 | 22.3699929 | −7.9% | -| `leaf_temp` driver = 35 °C | 2.1302e-04 | 6.4472e-07 | ÷331 | -| Penman-Monteith on | 2.2034982 | 1.1638497 | **−47.2%** | - -⚠️ **plant pins 25 °C itself at its defaults**, which is what makes the first row -exact: `TF24_Environment` sets `leaf_temp` as a *constant* extrinsic driver at 25 and -`use_energy_balance` defaults to 0. So a default plant run is unaffected, and the -exposure is entirely in the two configurations that leave 25 °C. - -⚠️ **The Penman-Monteith row is the one to carry forward.** On that path leaf -temperature reaches **62 °C, up to +22 K above air temperature** (measured over PAR -400–2000 × Tair 20–40 × VPD 1–3), so a PM leaf at 25 °C air already sits at 32.9 °C -and loses 23% of its assimilation. `Tleaf` itself moved on 22 of 90 cells, because -the energy balance couples back through transpiration — on that path leaf temperature -is an output, not an input. - -plant needs no source change: it never calls `set_traits`, so the fourteenth argument -is invisible to it, and it binds only `R_d_` of the respiration fields. Its -leaf/TF24 test files give **486 checks, 0 failures** and one error, and that error is -**present identically on the control** — pre-existing on plant develop, not #41. - -**Still not covered, and recorded so the next attempt starts from the real -obstacle**: `compare_with_plant.R`, which compares against plant's own independent -`Leaf`, still does not run. Its header blames the constructor signature; that is no -longer the obstacle. Against plant at 76df7169 both `Leaf()` and `set_physiology()` -work, and what stops it is `root_collar_psi_` versus `opt_root_psi_` — the #25 -rename, which flipped the sign — on top of results deliberately moved by #15, 11a, -11b, #25, #77 and #84. That is issue #64 and it needs a decision about the reference, -not a rename. - - -## The golden grid has a temperature axis: 288 points become 1152 (#41) - -⚠️ **The golden file was blind to every temperature response in the model, and had -been all along.** Its grid was 6 ψ_soil × 4 PPFD × 4 VPD × 3 layer counts, **all at -a leaf temperature of 25 °C** — and the reference values of Vcmax, Jmax and R_d are -*defined* at 25 °C, so a change to any response curve is inert there **by -construction**. #41 changed R_d's shape at every temperature except 25 °C and this -file did not move a bit. The same blindness covered the thirteen temperature-response -parameters bound just before it. - -The grid is now that same state space at **15 / 25 / 35 / 40 °C** — 1152 rows, with a -`leaf_temp` column. 40 °C is in the list deliberately: it is where the response bites -hardest, and the extra shut-down rows at the hot end pin the temperature at which the -model stops having an operating point, which is a limit that moved in #41. - -**Regenerated deliberately, and the regeneration is checkable as an ADDITION rather -than taken on trust.** Temperature is the OUTERMOST loop, so the file is four -contiguous copies of the original grid, and the 25 °C block is **byte-identical** to -the pre-#41 file in all nine output columns. Nothing moved; 864 rows were added. - -**The classification is now counted per temperature, and it moves:** +| | phylloptim master | this branch | +|---|---|---| +| default (`vcmax_25` = 96) | 81.857087216483691 | 81.857087216483691 | +| `vcmax_25` = 60 | 0.40692 | 0.34336 | +| `vcmax_25` = 150 | 73.703 | 92.026 | -| T | interior | pinned wet | pinned dry | shutdown | -|---|---|---|---|---| -| 15 °C | 198 | 24 | 18 | 48 | -| 25 °C | 198 | 24 | 18 | 48 | -| 35 °C | 194 | 43 | 3 | 48 | -| 40 °C | 160 | 80 | 0 | 48 | +The default arm is bit-identical to all 17 digits. If a study wants respiration to +track Vcmax, that coupling belongs in the caller's parameterisation — plant's +`TF24_hyperpar` is where every other derived parameter is already computed. -A single total would have let points move between branches and still add up. The -direction is physical: a hot leaf assimilates less and respires more, so it has less -to gain from water and its optimum presses against the **wet** bound instead of the -dry one. The 48 shut-down rows are temperature-*independent*, which is also right — -those are the ψ_soil = 6 MPa rows, where hydraulics forbid transpiration whatever the -temperature. - -Two things the hot end does **not** reach, recorded so the zeros are not read as -coverage: `shade-death` (that is reached by light, not by heat) and the -compensation-point exit, which needs about 45 °C at the defaults. -`test_rd_temperature_response` covers the latter. - -`tests/cpp/bench_solve.cpp` deliberately did **not** follow. A timing baseline is -only useful against its own history — `tools/cost-baseline.tsv` and -`tools/bench_history.sh` compare across commits — so quadrupling its workload would -end that history to measure nothing new about the solve. Its comment no longer claims -to cover the same state space as the baseline. - -`tests/validate/compare_with_plant.R` mirrors the grid, so it gained the axis too. -⚠️ At 15 / 35 / 40 °C phylloptim and a pre-#41 plant are *expected* to differ, since -R_d's shape changed; `rd_tracks_vcmax_` is what makes that arm comparable. - - -## An escape hatch back to the pre-#41 respiration shape (#41) - -`rd_tracks_vcmax_` makes `R_d` be `rd_to_vcmax_ratio_ * vcmax_(T)` again — Vcmax's -peaked Arrhenius — bit-identically to what this model computed before #41. - -⚠️ **This closes a reproducibility hole we made.** No combination of -`rd_q10_intercept_` and `rd_q10_slope_` produces a *peaked* function, so with #41 -landed and no flag, **any published plant result computed under the old shape could -not be regenerated with this code.** It is not a deprecation switch or a -compatibility mode: the default shape is the correct one, and this reproduces a shape -known to be wrong above the thermal optimum. It exists so an old number can be -checked, and so the plant revalidation is a controlled A/B — the flag on with -temperature varying isolates the shape change from everything else on the branch — -rather than an argument. - -The two shapes agree exactly at 25 °C and diverge in **opposite directions** above -the thermal optimum: at 45 °C the peaked curve gives `R_d` 0.507, below its 25 °C -value of 1.440, where the declining-Q10 form gives 3.618. That opposition is why a -flag was needed and a parameter would not do. - -Three things it had to get right: - -- ⚠️ **It is in the temperature cache key.** Flipping it changes `R_d` at every - temperature but 25 °C while leaving every other key entry alone, so a key that - missed it would take a cache *hit* on the first `set_physiology()` after the flip - and run the whole A/B under whichever shape was seated first (hazard 10). -- ⚠️ **Setting it together with a measured `R_d_25` is REFUSED, not resolved.** The - peaked curve has no reading in which a measured reference value means anything, so - a caller who sets both is confused about which model they are running. -- **The branch is asserted bit-exactly**, against the same `ratio * vcmax_(T)` - emulation the blast-radius table used to build for itself — and that table's "old" - column is now the flag rather than an emulation of it, so the table is evidence the - hatch reproduces what plant used to compute rather than only a record of what - changed. Its printed numbers are unchanged. - -`plant` binds `Leaf`'s fields by name in its own `RcppR6_classes.yml`, so it needs -its own line for this field. - -**No cost**: 3.03–3.04 µs/solve on both arms, interleaved ×3 from one tree, with -identical checksums — inside the ±0.01 within-process noise. The key is compared -once per `set_physiology()`, not per solve iteration. Golden file bit-identical. - - -## `R_d_25` is settable and differentiable from R, at its default as well as when pinned (#41) - -`leaf_traits(R_d_25 = 0.525)` now reaches the model, and `"R_d_25"` is a `pars` -entry for both `leaf_gradient()` and `leaf_gradient_batch()`. Measured at one -observation: `dA/dR_d_25 = -0.24874` against a central difference of the solve at -`-0.24868`. ⚠️ Not ≈ −1, because the optimiser moves the operating point in -response, so the total derivative is well below the direct `-R_d` term. - -`R_d_25` defaults to `NA`, meaning *derive it as `rd_to_vcmax_ratio_ * vcmax_25`*, -and **the sentinel is resolved where `theta` is built** rather than carried into it. -That is what makes the parameter differentiable AT THE DEFAULT — a calibration does -not have to pin a value first — and it is also what the batch path needs: `theta` -there is a numeric matrix in which an `NA` is indistinguishable from a trait the -caller forgot, which is how it first failed (`` `traits` is missing: NA ``). - -⚠️ **`dY/dvcmax_25` IS NOW A PARTIAL DERIVATIVE AT FIXED RESPIRATION.** It used to -carry `rd_to_vcmax_ratio_ * dY/dR_d_25` as well, because `R_d` was derived from -`vcmax_25` and there was nothing else to hold it. That is the correct Jacobian -column for a fit that moves both, and the total derivative is recovered exactly by -adding the `R_d_25` column back. - -**Measured blast radius, and it is confined to that one column.** Of the 60 cells in -`tests/testthat/gradient_golden.tsv`, **14 moved and all 14 are `vcmax_25`**, by 16% -to 250%; every `stem_b`, `psi_crit`, `leaf_specific_conductance_max` and -`resistance` cell is bit-identical, as is every solved value. The 250% is the -five-layer row, where the two terms nearly cancelled. The chain rule reconstructs -all 14 old numbers — exactly where both arms are exact, and to 2.8e-04 at worst -where they are not, that residual being the direct term's own finite-difference -round-off (it falls to 2.5e-06 at `step = 1e-4`). - -The sharpest case is a shut-down operating point, where `A = -R_d` exactly: -`dA/dvcmax_25` was `-0.015` and is now **exactly 0**, with the `-1` moved to -`dA/dR_d_25`. `R_d_25` is recorded at all five golden operating points now, so the -new column has a baseline of its own. - -Two traps worth carrying, both of which cost time here: - -- ⚠️ **The parameter enumeration deliberately does NOT follow `set_traits()`' - argument order.** `R_d_25` is `set_traits()`' fourteenth argument but the - enumeration's sixteenth, appended after the two non-traits, because inserting it - at 13 would displace `par_kmax` and `par_resistance` — and C++ indexes `theta` by - position. Appending is safe; reordering differentiates the wrong parameter and - returns plausible numbers. -- ⚠️ **`.gradient_setter()`'s positional trait call is where this broke**, at run - time, with `argument R_d_25 is missing` raised inside the generated binding — a - message naming neither the call nor the arity. Its own comment predicted exactly - that. The arity is asserted in `test-gradient.R`. - -The generated `Leaf` constructor still does not take `R_d_25`; `leaf_model()` -assigns the field afterwards, and `test-surface.R` now records that as a fact and -checks the assignment is really there — without it, `leaf_traits(R_d_25 = )` would -be accepted and silently ignored, which is worse than not offering the argument. - -## A leaf too hot to gain carbon shuts down instead of throwing - -Raising `R_d` makes a case reachable that the prescribed-temperature path could not -previously reach: net assimilation negative across the whole `[gamma*, ca]` bracket, -so `psi_stem_to_ci` has no supply-equals-demand root and `toms748_solve` throws -`Parameters a and b do not bracket the root`. At the defaults that happens by 45 °C. - -The model already knew the physical case — `ci_at_compensation_point_` places `ci` -at the compensation point — but that fallback only fired on the energy-balance path. -It now applies on the default path too, and the answer is a shut-down operating -point rather than an exception. The temperature at which the model stops having an -operating point is pinned as a measurement rather than avoided by choosing a cooler -sweep. - -## ⚠️ R_d rises with temperature now, on Tjoelker's declining Q10 (#41) - -`R_d` was `rd_to_vcmax_ratio_ * vcmax_(T)`, so it inherited Vcmax's **peaked** -Arrhenius and therefore **fell** above the thermal optimum, where real dark -respiration rises. No value of the ratio repairs a function of the wrong shape, so -the shape is what changed: +`R_d_25` is also a `pars` entry for `leaf_gradient()` and `leaf_gradient_batch()`: +`dA/dR_d_25 = -0.24874` against a central difference of the solve at −0.24868. ⚠️ Not +≈ −1, because the optimiser moves the operating point in response. `dY/dvcmax_25` is +correspondingly a **partial** at fixed respiration; a fit that moves both adds the +two columns. -``` -Q10(T) = rd_q10_intercept_ - rd_q10_slope_ * (T + 25) / 2 3.09, 0.0430 -R_d(T) = R_d_25 * Q10(T)^((T - 25) / 10) -``` - -**This moves results at every temperature except 25 °C, deliberately.** The 25 °C -agreement is exact rather than approximate: the reference value defaults to -`rd_to_vcmax_ratio_ * vcmax_25`, and `vcmax_(25) == vcmax_25` by construction of the -peaked Arrhenius. +**Blast radius**, and it is zero at 25 °C by construction — the trait *is* the value +there: | T | R_d old → new | A old → new | | |---|---|---|---| @@ -252,20 +58,70 @@ peaked Arrhenius. | 40 °C | 1.012 → 3.171 | 1.8265 → 0.8555 | −53.16% | | 45 °C | 0.507 → 3.618 | 0.6339 → −3.6176 | shut-down | -⚠️ **The golden grid is entirely at 25 °C, so its bit-identicality is BY -CONSTRUCTION and is not evidence about this change.** `test_rd_temperature_response` -is. The same blindness covers the thirteen temperature-response parameters bound -earlier. +Two further consequences: + +- **A leaf too hot to gain carbon now shuts down instead of throwing.** A higher R_d + can drive net assimilation negative across the whole `[gamma*, ca]` bracket, and + then `psi_stem_to_ci` has no supply-equals-demand root. The model already knew that + case — `ci_at_compensation_point_` — but only on the energy-balance path; it now + applies on the default path too, and the temperature at which the model stops + having an operating point is pinned as a measurement. +- **On plant's Penman-Monteith path the change is large**, because leaf temperature + there reaches **62 °C, up to +22 K above air**: offspring production −47.2% + (2.2035 → 1.1638). ⚠️ plant's *default* configuration is unaffected — it sets + `leaf_temp` as a constant 25 °C driver with PM off — so the exposure is entirely in + configurations that leave 25 °C. + +`R_d_25` is the fourteenth entry of the gradient enumeration, i.e. in `set_traits()`' +own argument order, with `leaf_specific_conductance_max` and `resistance` after it. +Every index in `gradient.hpp` now has a name (`par_vcmax_25`, `par_R_d_25`, ...) so +nothing indexes `theta` with a bare integer. + +**API removal:** `rd_to_vcmax_ratio_` is gone, from both C++ and the R bindings. It +existed only as the fraction, and there is no fraction now. plant never used it. + +## The golden grid gains a temperature axis: 288 points become 576 (#41) + +⚠️ **A grid at one leaf temperature is blind to every temperature response in the +model**, and this one was, at 25 °C. The reference values of Vcmax, Jmax and R_d are +*defined* there, so a change to any response curve is inert **by construction** — the +respiration change above moved results at every temperature except 25 °C and this +file did not move a bit. -**A constant Q10 remains reachable** — slope zero, intercept the value — and that is -asserted, because it is the escape hatch for anyone who wants the conventional form. -A constant Q10 of 2 was in fact implemented first and rejected on measurement: `R_d` -4.07 at 40 °C, −73% on A, and no operating point at all by 45 °C. +The grid is now the same 288 operating points at **25 and 40 °C**, with a `leaf_temp` +column. 40 °C is where the response bites hardest, and the extra pinned rows at the +hot end are a feature. -⚠️ **Slope zero does NOT recover the pre-#41 shape**, which was peaked. No -combination of intercept and slope produces a peaked function, so the old behaviour -is not reachable through these two parameters. +**Regenerated deliberately, and checkable as an addition**: temperature is the +outermost loop, so the 25 °C block is **byte-identical** to the previous file in all +nine output columns. 288 rows added, none moved. + +The classification is counted per temperature now, because it moves: + +| T | interior | pinned wet | pinned dry | shutdown | +|---|---|---|---|---| +| 25 °C | 198 | 24 | 18 | 48 | +| 40 °C | 160 | 80 | 0 | 48 | +A single total would let points move between branches and still add up. The direction +is physical: a hot leaf assimilates less and respires more, so it has less to gain +from water and its optimum presses against the **wet** bound instead of the dry one. +The 48 shut-down rows do not move, because there it is hydraulics rather than heat +that forbids transpiration. + +`tests/cpp/bench_solve.cpp` deliberately stays at 288 points at 25 °C: a timing +baseline is only useful against its own history (`tools/cost-baseline.tsv`, +`tools/bench_history.sh`). + +## The recorded gradients have their own tolerance + +`gradient_golden.tsv` used the solved-output baseline's tolerance, and that was +wrong. A value there is a **finite difference**, so cross-platform it carries the +solve's ~1e-9 floor **divided by the step** — one amplification more than the outputs +it is built from. The step is relative, so the smallest-magnitude parameter sets the +tolerance for the whole file: `R_d_25` is 1.44 where `vcmax_25` is 96, a 67× smaller +absolute step, and it disagrees 1.3e-03 on Linux against 1.3e-04 for the other +columns. `gradient_golden_tolerance()` is 5e-03, with the arithmetic. ## The temperature cache now keys on everything it reads, so R_d is genuinely settable (#41) diff --git a/PLAN.md b/PLAN.md index 986536d..8211c66 100644 --- a/PLAN.md +++ b/PLAN.md @@ -35,7 +35,7 @@ the user-visible history. | [#34](https://github.com/traitecoevo/phylloptim/issues/34) | 6d | Delete plant's `Leaf` bindings | Unblocked (plant #591 merged, and #33 is done). The hazard-7 payoff, and the only stage that can break plant | | [#38](https://github.com/traitecoevo/phylloptim/issues/38) | 38 | `psi_crit` above the curve's domain fails with an error naming neither | Bounds how far `stem_b` can move in one step; see 11f | | [#40](https://github.com/traitecoevo/phylloptim/issues/40) | 40 | Cross-validate the Medlyn path against `plantecophys` | From #6. Ties to #3, which needs Medlyn first-class | -| [#41](https://github.com/traitecoevo/phylloptim/issues/41) | 41 | `R_d`: settable, differentiable, and rising with temperature | **DONE.** From #6. The scale was the smaller half — the SHAPE was peaked and fell above the thermal optimum. Bit-identical at plant's defaults, −47% offspring production on the PM path | +| [#41](https://github.com/traitecoevo/phylloptim/issues/41) | 41 | `R_d_25` is a trait, and respiration rises with temperature | **DONE.** From #6. The scale was the smaller half — the SHAPE was peaked and fell above the thermal optimum. Bit-identical at plant's defaults; −47% offspring production on the PM path | | [#49](https://github.com/traitecoevo/phylloptim/issues/49) | 14 | Is `kmax ~ h^-1` defensible? Koçillari et al. 2021 find no height trend | Split out of item 14, which had it filed nowhere | | [#50](https://github.com/traitecoevo/phylloptim/issues/50) | 8 | `H2O_CO2_stom_diff_ratio` is 1.67, the g1 literature uses 1.6 | **2.2% offset** in every reported `g1_eff` | | [#51](https://github.com/traitecoevo/phylloptim/issues/51) | 10c | `kg_to_mol_h2o` and `kg_per_mol_h2o` are not reciprocals | **0.028%**. The bit-identity baseline it was waiting for now exists | @@ -531,59 +531,38 @@ by root-finding, which is worth considering on its own merits. Found doing #6. ## 41. `R_d` — DONE, and the shape mattered more than the scale -The original complaint: `rd_to_vcmax_ratio_` became a settable C++ member in #15 but -was **absent from `inst/RcppR6_classes.yml`** and not a constructor argument, so from -R a fixed 0.015 was imposed, and `R_d_`, though bound read/write, was recomputed by -every `set_physiology()`. Sabot's data imply ratios of **0.0046–0.0302** — a factor -of 6.5 — and for *Q. ilex* the model used 0.914 against the data's 0.525, a **74% Rd -overstatement** and a systematic ~4% species-varying bias in A. +The original complaint: `rd_to_vcmax_ratio_` was a fixed 0.015 and unreachable from +R, while Sabot's data imply 0.0046–0.0302 across 16 species — for *Q. ilex* the model +used 0.914 against the data's 0.525, a **74% overstatement** and a systematic ~4% +species-varying bias in A. -All of that is fixed: the temperature cache keys on everything it reads, `R_d_25` is -a trait, and it is differentiable at its default. But the reachable part turned out to -be the smaller half of the problem. - -⚠️ **THE SHAPE WAS WRONG, NOT JUST THE SCALE, AND NO VALUE OF THE RATIO COULD FIX -IT.** `R_d` was `ratio * vcmax_(T)`, so it inherited Vcmax's **peaked** Arrhenius and +⚠️ **The shape was wrong, not just the scale, and no value of the ratio could fix +it.** `R_d` was `ratio * vcmax_(T)`, so it inherited Vcmax's **peaked** Arrhenius and therefore **fell** above the thermal optimum, where real dark respiration rises — the opposite direction, and an order of magnitude out by 50 °C. Replaced with Tjoelker's declining Q10. A constant Q10 = 2 was implemented first and rejected on measurement (R_d 4.07 at 40 °C, −73% on A, no operating point at all by 45 °C). -`rd_tracks_vcmax_` is the way back to the old shape, and it exists because without it -**no published plant result computed under the old shape could be regenerated** — a -reproducibility hole this item created. It is also what makes the revalidation a -controlled A/B rather than an argument. +`R_d_25` is now a trait like any other: default **1.44** (`0.015 * 96`, the same +double the old derivation gave), no sentinel, no fallback, and an unset value fails. +`rd_to_vcmax_ratio_` is deleted. -**What the A/B says.** Over the 1152-point golden grid -(`tests/validate/rd_shape_grid.cpp`), against phylloptim at `origin/master`: +**Back-compatibility, measured.** plant's TF24 SCM offspring production is +**bit-identical at its defaults** — 81.857087216483691 both sides — because plant's +`vcmax_25` is 96 and it pins `leaf_temp` as a constant 25 °C driver with PM off. +⚠️ Two configurations do move, and both are the point rather than a defect: -| arm | cells differing | verdict | +| | master | now | |---|---|---| -| default, 25 °C only | **0 of 2592** | the control holds | -| `rd_tracks_vcmax_ = TRUE`, all four temperatures | **0 of 10368** | the whole of #41 is the shape and nothing else | -| default, all four temperatures | 6018 of 10368 | the blast radius | - -The second row is the strong one: the cache key, the settable `R_d_25`, the shut-down -exit and the R API are jointly **behaviour-neutral**, proved rather than argued. - -Assimilation moves +0.05 to +3.51% at 15 °C, exactly 0 at 25 °C, −5.7 to −100% at -35 °C and −35 to −213% at 40 °C. **No row changed feasibility** — the 48 shut-down -rows per temperature are the same rows. Of the 864 rows whose A moves, 269 keep their -exact operating point: 144 shut down, and 125 sit pinned to a bound temperature does -not move, so only their carbon balance changes. - -**On the plant side** (`tests/validate/rd_shape_arms.R`), TF24 SCM offspring -production is **bit-identical at plant's defaults** — because `TF24_Environment` pins -`leaf_temp` as a constant 25 °C driver with Penman-Monteith off, so #41 is inert there -by construction — then **−7.9%** at a 30 °C driver, **÷331** at 35 °C, and **−47.2%** -with PM on. The PM row is the one to carry forward: leaf temperature there runs to -**62 °C, up to +22 K above air**, and `Tleaf` itself moves, because the energy balance -couples back through transpiration. - -⚠️ **The golden file was blind to all of this and had been all along** — 288 points at -one temperature, where every reference value is defined. It has a temperature axis -now. Read the developer guide's golden-file section before trusting a bit-identical -run about any temperature response. +| `vcmax_25` = 60 / 150 (respiration no longer follows Vcmax) | 0.40692 / 73.703 | 0.34336 / 92.026 | +| Penman-Monteith on (Tleaf to 62 °C, +22 K above air) | 2.2035 | 1.1638 | + +A study that wants respiration to track Vcmax should say so in its own +parameterisation — plant's `TF24_hyperpar` is where every other derived parameter is +computed. + +⚠️ **The golden file was blind to all of this** — 288 points at one temperature, where +every reference value is defined. It now carries a 40 °C block as well. **Still open:** `compare_with_plant.R`, against plant's own independent `Leaf`, does not run — item 64. The obstacle is not the constructor signature its header blames: @@ -591,9 +570,6 @@ against plant at 76df7169 both `Leaf()` and `set_physiology()` work, and what st is `root_collar_psi_` versus `opt_root_psi_` (the #25 rename, which flipped the sign) on top of results deliberately moved by #15, 11a, 11b, #25, #77 and #84. -⚠️ Item 10b's claim that this parameter "is now settable" was true of C++ and false -from R; it is now true of both. - ## 14. Naming, home, publication The name is settled — `phylloptim`, in diff --git a/R/RcppExports.R b/R/RcppExports.R index 819e202..04454f5 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -453,14 +453,6 @@ Leaf__ko_ha___set <- function(obj_, value) { invisible(.Call('_phylloptim_Leaf__ko_ha___set', PACKAGE = 'phylloptim', obj_, value)) } -Leaf__rd_to_vcmax_ratio___get <- function(obj_) { - .Call('_phylloptim_Leaf__rd_to_vcmax_ratio___get', PACKAGE = 'phylloptim', obj_) -} - -Leaf__rd_to_vcmax_ratio___set <- function(obj_, value) { - invisible(.Call('_phylloptim_Leaf__rd_to_vcmax_ratio___set', PACKAGE = 'phylloptim', obj_, value)) -} - Leaf__R_d_25__get <- function(obj_) { .Call('_phylloptim_Leaf__R_d_25__get', PACKAGE = 'phylloptim', obj_) } @@ -485,14 +477,6 @@ Leaf__rd_q10_slope___set <- function(obj_, value) { invisible(.Call('_phylloptim_Leaf__rd_q10_slope___set', PACKAGE = 'phylloptim', obj_, value)) } -Leaf__rd_tracks_vcmax___get <- function(obj_) { - .Call('_phylloptim_Leaf__rd_tracks_vcmax___get', PACKAGE = 'phylloptim', obj_) -} - -Leaf__rd_tracks_vcmax___set <- function(obj_, value) { - invisible(.Call('_phylloptim_Leaf__rd_tracks_vcmax___set', PACKAGE = 'phylloptim', obj_, value)) -} - Leaf__PPFD___get <- function(obj_) { .Call('_phylloptim_Leaf__PPFD___get', PACKAGE = 'phylloptim', obj_) } diff --git a/R/RcppR6.R b/R/RcppR6.R index 8fa2ad1..f798ac6 100644 --- a/R/RcppR6.R +++ b/R/RcppR6.R @@ -1,6 +1,6 @@ ## Generated by RcppR6: do not edit by hand ## Version: 0.2.4 -## Hash: 60b3e38c507c8fe5f85c1d7372f9dd00 +## Hash: abbaf8a5425a985fb81802acd9b06f64 ##' @importFrom Rcpp evalCpp ##' @importFrom R6 R6Class @@ -460,13 +460,6 @@ NULL Leaf__ko_ha___set(self, value) } }, - rd_to_vcmax_ratio_ = function(value) { - if (missing(value)) { - Leaf__rd_to_vcmax_ratio___get(self) - } else { - Leaf__rd_to_vcmax_ratio___set(self, value) - } - }, R_d_25 = function(value) { if (missing(value)) { Leaf__R_d_25__get(self) @@ -488,13 +481,6 @@ NULL Leaf__rd_q10_slope___set(self, value) } }, - rd_tracks_vcmax_ = function(value) { - if (missing(value)) { - Leaf__rd_tracks_vcmax___get(self) - } else { - Leaf__rd_tracks_vcmax___set(self, value) - } - }, PPFD_ = function(value) { if (missing(value)) { Leaf__PPFD___get(self) diff --git a/R/gradient-batch.R b/R/gradient-batch.R index a56177c..c5a9c56 100644 --- a/R/gradient-batch.R +++ b/R/gradient-batch.R @@ -326,6 +326,10 @@ leaf_gradient_batch <- function(batch, # observation -- and it reads the two non-traits back out of the resolved drivers # for the same reason that one does: theta has to hold the value the solve will # actually use. +# +# The two non-traits are `leaf_specific_conductance_max` and, on the +# single-potential path only, `resistance`: both are DRIVERS that a calibration +# fits like traits (#44), so the enumeration carries them after the traits. .gradient_theta_matrix <- function(batch, traits) { nr <- batch$theta_nrow par_names <- .gradient_par_names() @@ -333,31 +337,17 @@ leaf_gradient_batch <- function(batch, # By NAME, not by position. `leaf_traits()` is in `set_traits()`'s order and # test-gradient.R asserts it, but this is the one place a silent reordering # would produce plausible numbers for the wrong parameters. - # - # ⚠️ AND THE TRAITS ARE NO LONGER THE LEADING BLOCK OF `par_names`. `R_d_25` is a - # trait that the enumeration appends AFTER the two non-traits, so "all but the - # last two" reads `leaf_specific_conductance_max` as a trait -- which is how #41 - # first failed here, reporting "`traits` is missing: NA" -- where the NA was the - # NAME of a trait that does not exist, not a missing value. The names are taken - # by set difference and placed by `match()`, so - # neither end of the list is assumed contiguous. - non_traits <- c("leaf_specific_conductance_max", "resistance") - trait_names <- setdiff(par_names, non_traits) + trait_names <- par_names[seq_len(length(par_names) - 2L)] tv <- unlist(traits)[trait_names] - # The sentinel resolved here rather than passed through: see `.resolve_rd_25()`. - # It has to happen BEFORE the anyNA() check, which would otherwise read the - # default `R_d_25` as a missing trait. - tv[["R_d_25"]] <- .resolve_rd_25(tv[["R_d_25"]], tv[["vcmax_25"]], - batch$leaf$rd_to_vcmax_ratio_) if (anyNA(tv)) { stop("`traits` is missing: ", paste(trait_names[is.na(tv)], collapse = ", "), call. = FALSE) } - m[, match(trait_names, par_names)] <- rep(tv, each = nr) - m[, match("leaf_specific_conductance_max", par_names)] <- batch$kmax + m[, seq_along(tv)] <- rep(tv, each = nr) + m[, length(par_names) - 1L] <- batch$kmax # NA on the multi-layer path, where there is no such parameter and C++ never # reads the column. - m[, match("resistance", par_names)] <- batch$resistance + m[, length(par_names)] <- batch$resistance m } diff --git a/R/gradient.R b/R/gradient.R index 91f9d8c..920406b 100644 --- a/R/gradient.R +++ b/R/gradient.R @@ -87,10 +87,6 @@ set_traits <- function(x, traits) { } # Positional, in the C++ argument order, for the same reason leaf_model() is: # the ordering is written down once rather than at every call site. - # ⚠️ `R_d_25` is last and is usually NA -- the sentinel for "derive from - # vcmax_25". It must be passed rather than dropped: leaving it out would make a - # re-traited leaf differ from a fresh one built with the same traits, which is - # exactly the invariant test_set_traits_matches_a_fresh_leaf asserts bit-exactly. x$set_traits(traits$vcmax_25, traits$stem_c, traits$stem_b, traits$psi_crit, traits$root_c, traits$root_b, traits$root_psi_crit, traits$beta2, traits$jmax_25, traits$a, traits$curv_fact_elec_trans, @@ -255,17 +251,9 @@ set_traits <- function(x, traits) { ##' [leaf_traits()] names, plus `"leaf_specific_conductance_max"` and — on the ##' single-potential path only — `"resistance"`. Defaults to all of them. ##' -##' ⚠️ The ORDER of the enumeration is not `leaf_traits()`' order: `"R_d_25"` -##' comes last, after the two non-traits, because the C++ side indexes this list -##' by position and inserting it would have moved the other two. That matters -##' only if you build `theta` yourself; `pars` itself is matched by name. -##' -##' `"R_d_25"` is differentiable at its `NA` default, which is resolved to -##' `rd_to_vcmax_ratio_ * vcmax_25` before anything is perturbed. The -##' consequence worth knowing: `dY/dvcmax_25` is then a PARTIAL at fixed -##' respiration. It used to carry the respiration term as well, because `R_d` -##' was derived from `vcmax_25` with nothing else to hold it. Add -##' `rd_to_vcmax_ratio_ * dY/dR_d_25` for the total derivative. +##' `dY/dvcmax_25` is a PARTIAL at fixed respiration: `R_d_25` is its own trait, +##' so a fit that wants respiration to follow Vcmax moves both and adds the two +##' columns. ##' ##' `beta_R_H` and `beta_R_V` were here until #33 and are not any more: they ##' parameterise the root-architecture model, which the leaf no longer runs, so @@ -403,8 +391,12 @@ leaf_gradient <- function(psi_soil, atm_vpd = atm_vpd, ca = ca, leaf_temp = leaf_temp, atm_o2_kpa = atm_o2_kpa, atm_kpa = atm_kpa) + # The differentiable parameters: the fourteen traits, plus the two that are not + # traits and that a calibration nonetheless fits (#44). See .gradient_theta. + theta <- .gradient_theta(traits, leaf_specific_conductance_max, supply, + root_network) if (is.null(pars)) { - pars <- .gradient_available_pars(identical(supply$kind, "single")) + pars <- names(theta) } # Shared with leaf_gradient_batch(), so the two entry points cannot disagree # about which parameters exist or explain a rejection differently. @@ -419,20 +411,6 @@ leaf_gradient <- function(psi_soil, # a call in a per-observation fit. Construction is the single largest term on # this surface. l <- if (is.null(x)) leaf_model(traits, control, supply) else x - - # The differentiable parameters: the thirteen traits, plus `R_d_25` and the two - # that are not traits and that a calibration nonetheless fits (#44). See - # .gradient_theta. - # - # ⚠️ AFTER the leaf, because resolving `R_d_25`'s sentinel needs - # `rd_to_vcmax_ratio_`, which is a field of the leaf and not of `traits`. Reading - # it from `l` rather than defaulting it here is what keeps the resolved value - # equal to the one `set_physiology()` would have derived, including for a caller - # who passes an `x` carrying a non-default ratio. `pars` no longer comes from - # theta's names for the same reason: it is available earlier, and - # `.gradient_available_pars()` is the same list in the same order. - theta <- .gradient_theta(traits, leaf_specific_conductance_max, supply, - root_network, l$rd_to_vcmax_ratio_) reset <- .gradient_setter(l, traits, drivers, supply, fast_stem_curve) if (is.null(x)) { @@ -603,16 +581,8 @@ leaf_gradient <- function(psi_soil, nms <- NULL function() { if (is.null(nms)) { - # ⚠️ `R_d_25` GOES LAST, NOT IN leaf_traits()' ORDER, and this deviation is - # forced rather than chosen. C++ appends it at index 15 because putting it in - # `set_traits`' argument order would place it at 13 and displace `par_kmax` / - # `par_resistance` -- the reorder `gradient.hpp` warns is unsafe. The two - # lists must agree position-for-position, so R follows suit. The - # C++-versus-R comparison in `test-gradient-batch.R` is what holds them - # together; drop the `setdiff` and it fails there rather than silently - # differentiating the wrong parameter. - traits <- setdiff(names(.leaf_trait_defaults), "R_d_25") - nms <<- c(traits, "leaf_specific_conductance_max", "resistance", "R_d_25") + nms <<- c(names(.leaf_trait_defaults), "leaf_specific_conductance_max", + "resistance") } nms } @@ -671,66 +641,14 @@ leaf_gradient <- function(psi_soil, # and `dY/dtheta = dY/dtheta|_psi + (dY/dpsi)(dpsi*/dtheta)` hold for any # parameter profit depends on. What differs per parameter is only which setter # applies it, which is .gradient_setter's job. -.gradient_theta <- function(traits, kmax, supply, root_network, - rd_to_vcmax_ratio) { - # ⚠️ `R_d_25` LAST, matching `.gradient_par_names()` and C++'s `par_names()`. - # `unlist(traits)` alone would put it at position 14 -- leaf_traits()' own order - # -- which is NOT the enumeration order, because C++ appends it after the two - # non-traits rather than displacing them. Getting this wrong differentiates the - # wrong parameter silently, so it is built from the canonical name list rather - # than from whatever order the traits object happens to have. - tr <- unlist(traits) - theta <- c(tr[setdiff(names(tr), "R_d_25")], - leaf_specific_conductance_max = kmax) +.gradient_theta <- function(traits, kmax, supply, root_network) { + theta <- c(unlist(traits), leaf_specific_conductance_max = kmax) if (identical(supply$kind, "single")) { theta <- c(theta, resistance = root_network$r_R_V_sum[[1]]) } - theta <- c(theta, R_d_25 = .resolve_rd_25(tr[["R_d_25"]], tr[["vcmax_25"]], - rd_to_vcmax_ratio)) - stopifnot("theta must be in gradient_par_names() order" = - identical(names(theta), - intersect(.gradient_par_names(), names(theta)))) theta } -# `R_d_25`'s NA sentinel, resolved to the number the model would have derived. -# -# ⚠️ THETA MUST NEVER CARRY THE SENTINEL, and two separate things say so. -# -# * It is not a value the batch path can even represent. `theta` there is a -# numeric matrix, in which an NA is indistinguishable from a trait the caller -# forgot -- which is exactly how it was first reported ("`traits` is missing: -# NA"). And `NaN == NaN` is false, so nothing downstream could compare such a -# column against anything either. -# * A parameter whose value is "derive it" is not differentiable: perturbing NA -# gives NA. Left unresolved, `R_d_25` would become a gradient parameter only -# after a caller had already pinned a finite value -- the opposite of what a -# calibration that starts from the default needs. -# -# The substitution is `rd_to_vcmax_ratio_ * vcmax_25`, which is the same -# expression `Leaf::rd_reference()` evaluates, so the base point is BIT-IDENTICAL: -# one multiply of the same two doubles either side of the boundary. The ratio is -# read off the leaf rather than defaulted here, so there is no second copy of -# 0.015 to drift from the field's own default. -# -# ⚠️ WHAT IT DOES CHANGE IS THE `vcmax_25` DERIVATIVE, and that is deliberate: with -# `R_d_25` a parameter in its own right, `dY/dvcmax_25` is a PARTIAL at fixed -# respiration, where before it carried `ratio * dY/dR_d_25` as well. That is the -# correct Jacobian column for a fit that moves both, and the total derivative is -# recovered exactly as `dY/dvcmax_25 + ratio * dY/dR_d_25`. -# -# It is the only column that moves. Measured over `gradient_golden.tsv`'s five -# operating points: 14 of 60 recorded cells changed, ALL of them `vcmax_25`, by -# between 16% and 250% -- the 250% is the five-layer row, where the two terms -# nearly cancelled, so dropping one is not a small edit. The chain rule above -# reconstructs every one of the 14 old values, exactly where both arms are exact -# and to 2.8e-04 at worst where they are not (that residual is the direct term's -# own finite-difference round-off: it falls to 2.5e-06 at `step = 1e-4`). -# `dA/dvcmax_25` at a shut-down point is the cleanest case -- exactly -0.015 -# before, exactly 0 now, with the -1 moved to `dA/dR_d_25`. -.resolve_rd_25 <- function(R_d_25, vcmax_25, rd_to_vcmax_ratio) { - if (is.na(R_d_25)) rd_to_vcmax_ratio * vcmax_25 else R_d_25 -} # Push a parameter vector back onto the leaf, in the one order that is correct. # @@ -806,18 +724,10 @@ leaf_gradient <- function(psi_soil, # the #25 positive-magnitude invariants itself. Do not copy this pattern anywhere # the values are not already known-good. # ⚠️ POSITIONAL, so the count is load-bearing. `set_traits()`'s C++ signature and - # `leaf_traits()` must agree on FOURTEEN; if a trait is ever added, this call is - # the one place that will not fail to compile. test-gradient.R asserts the arity. - # - # ⚠️ THAT PREDICTION CAME TRUE. Adding `R_d_25` (#41) broke here and nowhere - # else, at run time, with "argument R_d_25 is missing" from inside the generated - # binding -- a message that names neither this line nor the trait count. The - # arity assertion in test-gradient.R is what should catch the next one. - # - # `tv` is in `leaf_traits()`' order, where R_d_25 is fourteenth -- which is - # set_traits' argument order. It is NOT `.gradient_par_names()` order, in which - # R_d_25 comes after the two non-traits; `theta[trait_names]` is what reconciles - # the two. + # `leaf_traits()` must agree on FOURTEEN, and adding a trait breaks here and + # nowhere else -- at run time, with "argument is missing" raised inside + # the generated binding, which names neither this line nor the count. That is + # how #41 broke; test-gradient.R asserts the arity so the next one is caught. tv <- theta[trait_names] apply_traits(tv[[1L]], tv[[2L]], tv[[3L]], tv[[4L]], tv[[5L]], tv[[6L]], tv[[7L]], tv[[8L]], tv[[9L]], tv[[10L]], tv[[11L]], tv[[12L]], diff --git a/R/leaf-model.R b/R/leaf-model.R index a47a1e8..090cc15 100644 --- a/R/leaf-model.R +++ b/R/leaf-model.R @@ -45,7 +45,8 @@ a = 0.30, curv_fact_elec_trans = 0.7, curv_fact_colim = 0.99, - cost_scale_TF24 = 7.5 + cost_scale_TF24 = 7.5, + R_d_25 = 1.44 ) .leaf_control_defaults <- list( @@ -86,15 +87,8 @@ ##' @param curv_fact_colim curvature of the colimited photosynthesis equation ##' @param cost_scale_TF24 cost parameter for the TF24 profit model ##' (umol m^-2 s^-1) -##' @param R_d_25 dark respiration at 25 C (umol m^-2 s^-1). `NA`, the default, -##' means *derive it* as `rd_to_vcmax_ratio_ * vcmax_25`, which is what the -##' model has always done; a number pins it and breaks that link. Unlike every -##' other trait it accepts `NA`, and it is the one trait the generated `Leaf` -##' constructor does not take -- [leaf_model()] assigns the field afterwards. -##' -##' Either way it is the value at 25 C only: respiration rises from there with -##' Tjoelker's declining-Q10 curve (#41), so pinning `R_d_25` fixes the -##' reference point and not the temperature response. +##' @param R_d_25 dark respiration at 25 C (umol m^-2 s^-1). It is the value at +##' 25 C only: respiration rises from there on Tjoelker's declining-Q10 curve. ##' ##' @section Where the two root-resistance constants went: ##' `beta_R_H` and `beta_R_V` were traits here until #33. They parameterise the @@ -125,28 +119,19 @@ leaf_traits <- function(vcmax_25 = 96, curv_fact_elec_trans = 0.7, curv_fact_colim = 0.99, cost_scale_TF24 = 7.5, - R_d_25 = NA_real_) { + R_d_25 = 1.44) { out <- list(vcmax_25 = vcmax_25, stem_c = stem_c, stem_b = stem_b, psi_crit = psi_crit, root_c = root_c, root_b = root_b, root_psi_crit = root_psi_crit, beta2 = beta2, jmax_25 = jmax_25, a = a, curv_fact_elec_trans = curv_fact_elec_trans, curv_fact_colim = curv_fact_colim, - cost_scale_TF24 = cost_scale_TF24) + cost_scale_TF24 = cost_scale_TF24, + R_d_25 = R_d_25) .check_scalars(out, "leaf_traits") - # ⚠️ `R_d_25` is checked SEPARATELY because `NA` is a legitimate value for it and - # `.check_scalars()` demands finiteness. NA means "derive as - # 0.015 * vcmax_25", i.e. the behaviour every other trait combination has always - # had; a number overrides that. Folding it into the loop above would reject the - # default. - if (!(is.numeric(R_d_25) && length(R_d_25) == 1L)) { - stop("leaf_traits(): R_d_25 must be a single number, or NA to derive it ", - "from vcmax_25", call. = FALSE) - } - if (!is.na(R_d_25) && R_d_25 < 0) { + if (R_d_25 < 0) { stop("leaf_traits(): R_d_25 must be non-negative", call. = FALSE) } - out$R_d_25 <- as.numeric(R_d_25) structure(out, class = c("leaf_traits", "list")) } @@ -388,11 +373,9 @@ leaf_model <- function(traits = leaf_traits(), control = leaf_control(), ci_niter = control$ci_niter, cost_scale_TF24 = traits$cost_scale_TF24 ) - # ⚠️ R_d_25 goes on AFTER construction, because the generated constructor does not - # take it -- and it must go on at all, or `leaf_traits(R_d_25 = 0.525)` would be - # accepted and silently ignored, which is worse than not offering the argument. - # Safe here: nothing has been solved yet, and the temperature cache keys on the - # resolved reference value, so the next set_drivers() picks it up. + # ⚠️ AFTER construction, because plant's RcppR6 bindings pin the generated + # constructor by arity so R_d_25 cannot be an argument to it. Without this line + # `leaf_traits(R_d_25 = )` would be accepted and silently ignored. l$R_d_25 <- traits$R_d_25 l$initialize_integrator(control$integration_rule, control$integration_tol) # After the integrator, because set_supply_single clears the solved state -- diff --git a/inst/RcppR6_classes.yml b/inst/RcppR6_classes.yml index 12e6109..f295715 100644 --- a/inst/RcppR6_classes.yml +++ b/inst/RcppR6_classes.yml @@ -166,37 +166,15 @@ Leaf: # of the reason to reach for this model -- needs to move them. Jones et al. # (2026) fit 35 C for both. # - # ⚠️ `rd_to_vcmax_ratio_` matters for a different reason. Rd is - # `rd_to_vcmax_ratio_ * vcmax_`, so it inherits Vcmax's PEAKED Arrhenius and - # therefore FALLS above the thermal optimum, where a Q10 respiration rises. - # It is fixed at 0.015 while Sabot's own data imply 0.0046 to 0.0302 across - # species -- a factor of 6.5 -- and for Q. ilex the model uses 0.914 against - # the data's 0.525, a 74% overstatement. - # - # ⚠️ ~~SETTING THESE DOES NOT RECOMPUTE ANYTHING.~~ **FIXED (#41).** This - # warning was true and is now obsolete, and the history is worth one line - # because the shape of the mistake recurs: the temperature cache was keyed on - # (leaf_temp_, atm_o2_kpa_) and on nothing else, justified by "same inputs -> - # bit-identical outputs, so reusing is exact". **Binding these parameters made - # that justification false** -- the outputs now depended on fourteen more - # inputs the key did not mention -- and the first response was to document the - # trap rather than repair the key. - # - # The key now covers every scalar `update_temperature_dependent_params()` - # reads, so setting any of these and re-supplying the drivers recomputes, as a - # caller would expect. `test_temperature_params_invalidate_cache` asserts it - # through the route a caller actually takes, and fails four ways without the - # fix. + # The temperature cache is keyed on every scalar + # `update_temperature_dependent_params()` reads, so setting any of these and + # re-supplying the drivers recomputes, as a caller would expect (#41). + # `test_temperature_params_invalidate_cache` asserts it through the route a + # caller actually takes. # # ⚠️ `set_traits()` is STILL the right way to change a TRAIT (`vcmax_25`, - # `jmax_25`, ...): the vulnerability splines and the solved operating point - # need clearing too, and the cache key does not do that. What is gone is the - # silent-wrong-number half of hazard 10 -- a bare trait write no longer leaves - # `vcmax_`/`jmax_`/`R_d_` describing the old value. - # - # Behaviour at the defaults is unchanged: the golden file is bit-identical and - # the solve is 2.99 vs 3.00 us/solve, interleaved x3 -- inside the +-0.01 - # within-process noise. + # `jmax_25`, ...): the vulnerability splines and the solved operating point need + # clearing too, and the cache key does not do that. vcmax_ha_: {type: double, access: field} vcmax_H_d_: {type: double, access: field} vcmax_d_S_: {type: double, access: field} @@ -209,29 +187,15 @@ Leaf: kc_ha_: {type: double, access: field} ko_25_: {type: double, access: field} ko_ha_: {type: double, access: field} - rd_to_vcmax_ratio_: {type: double, access: field} - # Dark respiration at 25 C. NA/NaN means "derive as rd_to_vcmax_ratio_ * - # vcmax_25" -- the historical behaviour -- and a number overrides it. Bound as a - # field as well as being a `set_traits()` argument, because `leaf_model()` needs - # to apply it after the generated constructor (which does not take it). + # Dark respiration at 25 C. Bound as a field as well as being a `set_traits()` + # argument, because plant's own bindings pin the generated constructor by arity + # so `leaf_model()` has to apply it afterwards. R_d_25: {type: double, access: field} # The Tjoelker (2001) declining-Q10 coefficients: # Q10(T) = rd_q10_intercept_ - rd_q10_slope_ * (T + 25) / 2 - # ⚠️ Set the slope to zero and the intercept IS a constant Q10, which is the - # escape hatch for anyone who wants the conventional form. A constant Q10 = 2 - # was the first implementation and was measured too aggressive at the top of the - # range: R_d 4.07 at 40 C, -73% on assimilation, and no operating point at all - # by 45 C. See NEWS for the blast radius. + # Set the slope to zero and the intercept IS a constant Q10. rd_q10_intercept_: {type: double, access: field} rd_q10_slope_: {type: double, access: field} - # ⚠️ THE PRE-#41 RESPIRATION SHAPE, and the only way back to it: R_d becomes - # rd_to_vcmax_ratio_ * vcmax_(T), bit-identical to what this model did before - # #41, and the two Q10 coefficients above are not consulted. It exists because - # no combination of them produces a PEAKED function, so without it no published - # plant result computed under the old shape could be regenerated. Bound so the - # plant A/B can be driven from R. Setting it together with a measured R_d_25 is - # refused rather than resolved. - rd_tracks_vcmax_: {type: bool, access: field} # --- drivers, as last set by set_physiology ------------------------------ PPFD_: {type: double, access: field} diff --git a/inst/include/phylloptim/gradient.hpp b/inst/include/phylloptim/gradient.hpp index 688c751..224d33c 100644 --- a/inst/include/phylloptim/gradient.hpp +++ b/inst/include/phylloptim/gradient.hpp @@ -63,30 +63,35 @@ namespace gradient { // --- the parameter enumeration, which R indexes into -------------------------- // -// The thirteen traits in `Leaf::set_traits`' argument order, then the two +// The fourteen traits in `Leaf::set_traits`' argument order, then the two // quantities a calibration fits that are not traits: the conductance driver and // the single-potential path's series resistance. // -// ⚠️ APPENDING IS SAFE AND REORDERING IS NOT. R names these positions in -// `.gradient_par_names` and passes integer indices, so a swap here silently -// differentiates the wrong parameter. `test-gradient-batch.R` reads the names -// back out of C++ and compares them with R's, so the two cannot drift apart -// without a failure. -inline constexpr int n_traits = 13; +// ⚠️ R INDEXES THESE POSITIONS, so a reordering silently differentiates the wrong +// parameter. `test-gradient-batch.R` reads the names back out of C++ and compares +// them with R's, so the two cannot drift apart without a failure. +inline constexpr int n_traits = 14; inline constexpr int n_pars = 16; -// The indices the code below has to know by name: one takes the fast homogeneity -// path, and the two non-traits take a relative step. +// Every index by name, so nothing below indexes `theta` with a bare integer. +// The first `n_traits` are `set_traits`' arguments in its order, which is also +// `leaf_traits()`'; the two non-traits follow and take a relative step. +inline constexpr int par_vcmax_25 = 0; +inline constexpr int par_stem_c = 1; inline constexpr int par_stem_b = 2; -inline constexpr int par_kmax = 13; -inline constexpr int par_resistance = 14; -// ⚠️ `R_d_25` IS A TRAIT AND IS APPENDED AT THE END RATHER THAN PUT IN -// `set_traits`' ARGUMENT ORDER, WHICH WOULD PLACE IT AT 13. That would displace -// `par_kmax` and `par_resistance` -- a reorder, which the warning above says is -// exactly the unsafe move. So this enumeration and `set_traits`' argument order -// agree for the first thirteen and deliberately diverge here; `set_setter` passes -// `theta[par_R_d_25]` as that function's fourteenth argument. -inline constexpr int par_R_d_25 = 15; +inline constexpr int par_psi_crit = 3; +inline constexpr int par_root_c = 4; +inline constexpr int par_root_b = 5; +inline constexpr int par_root_psi_crit = 6; +inline constexpr int par_beta2 = 7; +inline constexpr int par_jmax_25 = 8; +inline constexpr int par_a = 9; +inline constexpr int par_curv_fact_elec_trans = 10; +inline constexpr int par_curv_fact_colim = 11; +inline constexpr int par_cost_scale_TF24 = 12; +inline constexpr int par_R_d_25 = 13; +inline constexpr int par_kmax = 14; +inline constexpr int par_resistance = 15; inline const std::vector& par_names() { static const std::vector names{ @@ -94,10 +99,9 @@ inline const std::vector& par_names() { "psi_crit", "root_c", "root_b", "root_psi_crit", "beta2", "jmax_25", "a", "curv_fact_elec_trans", "curv_fact_colim", - "cost_scale_TF24", + "cost_scale_TF24", "R_d_25", "leaf_specific_conductance_max", - "resistance", - "R_d_25"}; + "resistance"}; return names; } @@ -276,9 +280,12 @@ inline void apply(Leaf& l, const double* theta, const Drivers& d, bool single, l.perturb_stem_b(theta[par_stem_b]); return; } - l.set_traits(theta[0], theta[1], theta[2], theta[3], theta[4], theta[5], - theta[6], theta[7], theta[8], theta[9], theta[10], theta[11], - theta[12], theta[par_R_d_25]); + l.set_traits(theta[par_vcmax_25], theta[par_stem_c], theta[par_stem_b], + theta[par_psi_crit], theta[par_root_c], theta[par_root_b], + theta[par_root_psi_crit], theta[par_beta2], theta[par_jmax_25], + theta[par_a], theta[par_curv_fact_elec_trans], + theta[par_curv_fact_colim], theta[par_cost_scale_TF24], + theta[par_R_d_25]); if (single) { // R's `series_resistance()`: a default-constructed network carrying one // series resistance in `r_R_V_sum`, which is that field's own meaning with diff --git a/inst/include/phylloptim/leaf_model.hpp b/inst/include/phylloptim/leaf_model.hpp index 6b477e4..4e8a232 100644 --- a/inst/include/phylloptim/leaf_model.hpp +++ b/inst/include/phylloptim/leaf_model.hpp @@ -335,75 +335,31 @@ class Leaf { double kc_ha_ = phylloptim::kc_ha; double ko_25_ = phylloptim::ko_25; // Rubisco Km for O2, umol mol^-1 double ko_ha_ = phylloptim::ko_ha; - // Dark respiration as a fraction of vcmax. Was the bare literal 0.015 inline in - // update_temperature_dependent_params -- a named, species-variable parameter - // (Collatz/Farquhar) hiding as a magic number. - // - // ⚠️ THIS IS NOW A FALLBACK, NOT THE INTERFACE. It is consulted only when - // `R_d_25` is left unset; see there. - double rd_to_vcmax_ratio_ = 0.015; - // Dark respiration at the 25 C reference, umol m^-2 s^-1 -- the parameter a - // caller with a MEASURED respiration should set (#41). Many datasets report - // R_d directly (Sabot et al. give `Rlref` per site) and no ratio reproduces - // them: across their 16 species the implied ratio spans 0.0046 to 0.0302. - // - // ⚠️ THE DEFAULT IS A SENTINEL, NOT A NUMBER, AND THAT IS LOAD-BEARING. NaN - // means "derive as `rd_to_vcmax_ratio_ * vcmax_25`", which is exactly the old - // behaviour. Defaulting it to a *computed* `0.015 * vcmax_25` would look - // equivalent and would silently decouple respiration from Vcmax for every - // caller that sets `vcmax_25` afterwards -- which is what plant does for every - // individual. The sentinel keeps the derivation live until someone opts out of - // it. - double R_d_25 = std::numeric_limits::quiet_NaN(); + // Dark respiration at the 25 C reference, umol m^-2 s^-1. Many datasets report + // it directly (Sabot et al. give `Rlref` per site), and across their 16 species + // the implied fraction of vcmax_25 spans 0.0046 to 0.0302, so it is a trait in + // its own right rather than a fixed multiple of anything. + // + // The default is 0.015 * 96, the value the old vcmax-derived form gave at the + // default vcmax_25. Initialised here rather than in the constructors' init lists + // because plant's RcppR6 bindings pin the 17-argument constructor by arity, so + // this cannot become an 18th argument without breaking plant's generated glue. + double R_d_25 = 1.44; // Dark respiration's temperature response, Tjoelker et al. (2001): // - // R_d(T) = R_d(25) * Q10(T)^((T - 25) / 10) + // R_d(T) = R_d_25 * Q10(T)^((T - 25) / 10) // Q10(T) = rd_q10_intercept_ - rd_q10_slope_ * (T + 25) / 2 // - // where the Q10 is evaluated at the MEAN of the measurement and reference - // temperatures, which is the form the land-surface literature implements. - // - // ⚠️ THIS REPLACES A RESPONSE OF THE WRONG SHAPE, and it MOVES RESULTS at every - // temperature except 25 C. R_d used to be `rd_to_vcmax_ratio_ * vcmax_(T)`, so - // it inherited Vcmax's PEAKED Arrhenius and therefore FELL above the thermal - // optimum, where real dark respiration rises. No value of the ratio repaired - // that -- it was a scale on the wrong function. - // - // ⚠️ WHY A DECLINING Q10 RATHER THAN A CONSTANT 2.0, WHICH WAS TRIED FIRST AND - // MEASURED. A constant Q10 = 2 is conventional and is wrong at the top of the - // range in a way that matters here: it put R_d at 4.07 at 40 C -- 2.8x its 25 C - // value over 15 K -- cost 73% of assimilation there, and by 45 C left the solve - // with NO OPERATING POINT at all. That is not the physics; it is a constant Q10 - // used far outside where it holds, which is exactly what Tjoelker measured. - // - // ⚠️ A CONSTANT Q10 IS STILL REACHABLE, and deliberately so: set the slope to - // zero and the intercept is the constant. The declining form is the default - // rather than the only option. + // The Q10 is evaluated at the MEAN of the measurement and reference + // temperatures, which is the form the land-surface literature implements, and it + // DECLINES with temperature: a constant Q10 of 2 is too aggressive at the top of + // the range, putting R_d 2.8x its 25 C value over 15 K and leaving the solve no + // operating point at all by 45 C. + // + // Set the slope to zero and the intercept IS a constant Q10, for anyone who + // wants the conventional form. double rd_q10_intercept_ = 3.09; double rd_q10_slope_ = 0.0430; - // ⚠️ THE PRE-#41 RESPIRATION SHAPE, AND THE ONLY WAY BACK TO IT. With this set, - // `R_d_ = rd_to_vcmax_ratio_ * vcmax_` -- Vcmax's peaked Arrhenius, bit-identical - // to what this model did before #41 -- and the Q10 coefficients above are not - // consulted at all. - // - // It exists because the alternative was worse than a flag. No combination of - // `rd_q10_intercept_` and `rd_q10_slope_` produces a PEAKED function, so without - // this the old shape was unreachable and **no published plant result computed - // under it could be regenerated with this code**. That is a reproducibility hole - // we made, not a feature request. - // - // It is also what turns the plant revalidation from an argument into a controlled - // A/B: with the flag on, T varying, the answer must be bit-identical to - // pre-#41 plant, which isolates the shape change from everything else in the - // same branch. ⚠️ plant binds Leaf's fields by name in its own - // RcppR6_classes.yml, so it needs its own line for this one. - // - // ⚠️ NOT a deprecation switch and not a "compatibility mode": the default shape - // is the correct one, and this reproduces a shape known to be wrong above the - // thermal optimum. Setting it together with a measured `R_d_25` is REFUSED rather - // than resolved -- see update_temperature_dependent_params -- because the old - // shape has no reading in which a measured reference value means anything. - bool rd_tracks_vcmax_ = false; double atm_kpa_; // Conversion from a mixing ratio (umol mol^-1) to a partial pressure (Pa). // DERIVED from atm_kpa_, not a constant: it is 1e-6 * P, so the old @@ -462,10 +418,9 @@ class Leaf { // It used to be (leaf_temp_, atm_o2_kpa_) alone, and the argument for that was // "same inputs -> bit-identical outputs, so reusing is exact". That argument was // true while the temperature-response parameters were unreachable C++ members - // and became FALSE the moment they were bound to R: `l$rd_to_vcmax_ratio_ <- - // 0.03` followed by `set_drivers()` at the same temperature took a cache HIT and - // silently kept the old response. Measured before the fix: R_d stayed at 1.44 - // where a cold object gave 2.88, and A was unchanged to every digit. + // and became FALSE the moment they were bound to R: `l$rd_q10_slope_ <- 0` + // followed by `set_drivers()` at the same temperature took a cache HIT and + // silently kept the old response, with A unchanged to every digit. // // So the key is now every input of update_temperature_dependent_params(). Two // consequences worth knowing: @@ -479,15 +434,9 @@ class Leaf { // * the cost is 17 double comparisons per set_physiology() call, i.e. per // driver set, NOT per inner solve iteration. Measured: within run-to-run // noise on bench_solve. - static constexpr int photo_temp_key_size = 20; + static constexpr int photo_temp_key_size = 19; std::array photo_temp_cache_key_{}; std::array photo_temp_key() const; - // Dark respiration at 25 C, with the sentinel resolved. ⚠️ Used by BOTH the - // cache key and update_temperature_dependent_params, deliberately: keying on - // the raw `R_d_25` would put a NaN in an array compared with `==`, and - // `NaN == NaN` is false, so the cache would never hit for any caller who left - // the default -- a silent, total loss of caching that no test would notice. - double rd_reference() const; std::vector f_r; // TODO: move into environment? @@ -573,10 +522,6 @@ class Leaf { // resets both caches and requires set_physiology() before the next solve, exactly // as a fresh Leaf would. That last part is not conservatism: the derived // photosynthetic parameters really are unknown until the drivers are re-supplied. - // ⚠️ `R_d_25` is LAST and may be NaN, which is a value rather than an error -- - // the sentinel meaning "derive from rd_to_vcmax_ratio_ * vcmax_25". So it is - // deliberately outside check_psi_magnitudes' remit and must not be validated as - // finite. void set_traits(double vcmax_25, double stem_c, double stem_b, double psi_crit, double root_c, double root_b, double root_psi_crit, double beta2, double jmax_25, double a, @@ -1282,8 +1227,6 @@ inline void Leaf::set_traits(double vcmax_25_, double stem_c_, double stem_b_, curv_fact_elec_trans = curv_fact_elec_trans_; curv_fact_colim = curv_fact_colim_; cost_scale_TF24 = cost_scale_TF24_; - // NaN is a legitimate value here, so this is a plain assignment: it restores the - // "derive from the ratio" default as readily as it sets a measured value. R_d_25 = R_d_25_; roots_.root_c = root_c_; @@ -2484,12 +2427,9 @@ inline double Leaf::peak_arrh_curve(double Ea, double ref_value, double leaf_tem // depends on the per-call PPFD_ and is (re)computed here from the just-updated // jmax_ -- on the non-PM cache-hit path set_physiology refreshes it separately. // -// ⚠️ R_d INHERITS VCMAX'S PEAKED CURVE AND SO FALLS ABOVE THE THERMAL OPTIMUM, -// where dark respiration should rise. Matched at 25 C against a Q10 of 2, the -// two diverge in opposite directions: at 25/35/40/45/50 C this gives 0.395, -// 0.543, 0.466, 0.284, 0.135 against the Q10's 0.395, 0.790, 1.117, 1.580, -// 2.234 -- a factor of 16.5 apart by 50 C, and moving the wrong way. See the -// note at the R_d_ assignment below for why it is recorded rather than changed. +// R_d comes from R_d_25 and the declining Q10, so it RISES with temperature. +// It used to be a fraction of vcmax_(T) and therefore fell above the thermal +// optimum, which was the wrong direction (#41). // Every scalar update_temperature_dependent_params() below reads, in one place so // the cache key and the computation cannot drift apart. @@ -2509,22 +2449,7 @@ inline std::array Leaf::photo_temp_key() cons gamma_25_, gamma_ha_, kc_25_, kc_ha_, ko_25_, ko_ha_, - // ⚠️ The RESOLVED reference, not the raw `R_d_25`/ratio pair. That - // keeps NaN out of an `==` comparison, and it is also more complete: - // it invalidates on a change to whichever of the two is actually in - // force, and on neither when the other is. - rd_reference(), rd_q10_intercept_, rd_q10_slope_, - // A bool in an array of doubles, because the key is one contiguous - // `==` comparison and 0.0/1.0 compares exactly. It has to be here: - // flipping the flag changes R_d at every temperature but 25 C while - // leaving every other key entry alone, so without it the first - // set_physiology() after the flip takes a cache HIT and the whole - // A/B runs under whichever shape happened to be seated first. - rd_tracks_vcmax_ ? 1.0 : 0.0}; -} - -inline double Leaf::rd_reference() const { - return std::isnan(R_d_25) ? rd_to_vcmax_ratio_ * vcmax_25 : R_d_25; + R_d_25, rd_q10_intercept_, rd_q10_slope_}; } inline void Leaf::update_temperature_dependent_params(double leaf_temp) { @@ -2534,48 +2459,19 @@ inline void Leaf::update_temperature_dependent_params(double leaf_temp) { gamma_ = arrh_curve(gamma_ha_, gamma_25_, leaf_temp); ko_ = arrh_curve(ko_ha_, ko_25_, leaf_temp); kc_ = arrh_curve(kc_ha_, kc_25_, leaf_temp); - // ⚠️ RESPIRATION USED TO INHERIT VCMAX'S PEAKED CURVE AND THEREFORE FELL ABOVE - // THE THERMAL OPTIMUM, where real dark respiration rises. It was - // `rd_to_vcmax_ratio_ * vcmax_`, which peaks wherever Vcmax peaks and declines - // after. It diverged from a Q10 response in the opposite direction and by an - // order of magnitude by 50 C -- the numbers are tabulated in this function's doc - // block above, rather than here, because an indented block inside a function - // body is what Doxygen 1.9 on CI rejects. - // - // No value of the ratio repaired it -- a scale cannot fix a function of the - // wrong shape -- so the shape is what changed (#41). - // - // ⚠️ THIS MOVES RESULTS AT EVERY TEMPERATURE EXCEPT 25 C, deliberately, and the - // 25 C agreement is exact rather than approximate: the reference value defaults - // to `rd_to_vcmax_ratio_ * vcmax_25`, and `vcmax_(25) == vcmax_25` by - // construction of the peaked Arrhenius. ⚠️ The golden grid is entirely at 25 C, - // so it is bit-identical BY CONSTRUCTION and is not evidence about this change - // -- test_rd_temperature_response is. - // - // The reference value is a sentinel-defaulted parameter so that a caller who - // sets `vcmax_25` still gets respiration that scales with it (see R_d_25). - if (rd_tracks_vcmax_) { - // The pre-#41 shape, for reproducing a result computed under it. Written as - // the same expression the old code used rather than as `rd_reference() * - // vcmax_ / vcmax_25`, which is algebraically equal and not bit-equal -- - // bit-equality with the old model is the entire purpose of this branch. - // - // ⚠️ Refused rather than resolved. `R_d_25` is a measured reference value and - // the peaked curve has no reading in which one means anything, so a caller who - // sets both is confused about which model they are running. The Q10 - // coefficients above are simply unused here, which is different: they are - // defaults the caller did not ask for. - if (!std::isnan(R_d_25)) { - util::stop("rd_tracks_vcmax_ reproduces the pre-#41 shape, in which R_d is " - "rd_to_vcmax_ratio_ * vcmax_(T) and a measured R_d_25 has no " - "meaning. Set one or the other, not both."); - } - R_d_ = rd_to_vcmax_ratio_ * vcmax_; - } else { - const double q10 = - rd_q10_intercept_ - rd_q10_slope_ * (leaf_temp + 25.0) / 2.0; - R_d_ = rd_reference() * std::pow(q10, (leaf_temp - 25.0) / 10.0); - } + // Respiration RISES with temperature, on the declining Q10 above. ⚠️ It is + // exactly R_d_25 at 25 C and larger above, so any check taken at 25 C alone is + // blind to this whole response -- test_rd_temperature_response is what covers it. + // + // Fail rather than fall back: R_d_25 is a trait, and an unset one is a caller + // error, not a cue to derive something from vcmax. + if (!std::isfinite(R_d_25) || R_d_25 < 0.0) { + util::stop("R_d_25 must be a finite, non-negative dark respiration at 25 C; " + "got " + util::format_double(R_d_25)); + } + const double q10 = + rd_q10_intercept_ - rd_q10_slope_ * (leaf_temp + 25.0) / 2.0; + R_d_ = R_d_25 * std::pow(q10, (leaf_temp - 25.0) / 10.0); km_ = (kc_*umol_per_mol_to_Pa_)*(1 + (atm_o2_kpa_*kPa_to_Pa)/(ko_*umol_per_mol_to_Pa_)); electron_transport_ = electron_transport(); } diff --git a/man/leaf_gradient.Rd b/man/leaf_gradient.Rd index 54818fe..21bd86c 100644 --- a/man/leaf_gradient.Rd +++ b/man/leaf_gradient.Rd @@ -74,17 +74,9 @@ differentiate at} [leaf_traits()] names, plus `"leaf_specific_conductance_max"` and — on the single-potential path only — `"resistance"`. Defaults to all of them. - ⚠️ The ORDER of the enumeration is not `leaf_traits()`' order: `"R_d_25"` - comes last, after the two non-traits, because the C++ side indexes this list - by position and inserting it would have moved the other two. That matters - only if you build `theta` yourself; `pars` itself is matched by name. - - `"R_d_25"` is differentiable at its `NA` default, which is resolved to - `rd_to_vcmax_ratio_ * vcmax_25` before anything is perturbed. The - consequence worth knowing: `dY/dvcmax_25` is then a PARTIAL at fixed - respiration. It used to carry the respiration term as well, because `R_d` - was derived from `vcmax_25` with nothing else to hold it. Add - `rd_to_vcmax_ratio_ * dY/dR_d_25` for the total derivative. + `dY/dvcmax_25` is a PARTIAL at fixed respiration: `R_d_25` is its own trait, + so a fit that wants respiration to follow Vcmax moves both and adds the two + columns. `beta_R_H` and `beta_R_V` were here until #33 and are not any more: they parameterise the root-architecture model, which the leaf no longer runs, so diff --git a/man/leaf_traits.Rd b/man/leaf_traits.Rd index b6adf53..e585574 100644 --- a/man/leaf_traits.Rd +++ b/man/leaf_traits.Rd @@ -18,7 +18,7 @@ leaf_traits( curv_fact_elec_trans = 0.7, curv_fact_colim = 0.99, cost_scale_TF24 = 7.5, - R_d_25 = NA_real_ + R_d_25 = 1.44 ) } \arguments{ @@ -49,15 +49,8 @@ leaf_traits( \item{cost_scale_TF24}{cost parameter for the TF24 profit model (umol m^-2 s^-1)} -\item{R_d_25}{dark respiration at 25 C (umol m^-2 s^-1). `NA`, the default, - means *derive it* as `rd_to_vcmax_ratio_ * vcmax_25`, which is what the - model has always done; a number pins it and breaks that link. Unlike every - other trait it accepts `NA`, and it is the one trait the generated `Leaf` - constructor does not take -- [leaf_model()] assigns the field afterwards. - - Either way it is the value at 25 C only: respiration rises from there with - Tjoelker's declining-Q10 curve (#41), so pinning `R_d_25` fixes the - reference point and not the temperature response.} +\item{R_d_25}{dark respiration at 25 C (umol m^-2 s^-1). It is the value at +25 C only: respiration rises from there on Tjoelker's declining-Q10 curve.} } \value{ A `leaf_traits` object; a named list. diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 21e2e90..a086b7e 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -1329,28 +1329,6 @@ BEGIN_RCPP return R_NilValue; END_RCPP } -// Leaf__rd_to_vcmax_ratio___get -double Leaf__rd_to_vcmax_ratio___get(phylloptim::RcppR6::RcppR6 obj_); -RcppExport SEXP _phylloptim_Leaf__rd_to_vcmax_ratio___get(SEXP obj_SEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); - rcpp_result_gen = Rcpp::wrap(Leaf__rd_to_vcmax_ratio___get(obj_)); - return rcpp_result_gen; -END_RCPP -} -// Leaf__rd_to_vcmax_ratio___set -void Leaf__rd_to_vcmax_ratio___set(phylloptim::RcppR6::RcppR6 obj_, double value); -RcppExport SEXP _phylloptim_Leaf__rd_to_vcmax_ratio___set(SEXP obj_SEXP, SEXP valueSEXP) { -BEGIN_RCPP - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); - Rcpp::traits::input_parameter< double >::type value(valueSEXP); - Leaf__rd_to_vcmax_ratio___set(obj_, value); - return R_NilValue; -END_RCPP -} // Leaf__R_d_25__get double Leaf__R_d_25__get(phylloptim::RcppR6::RcppR6 obj_); RcppExport SEXP _phylloptim_Leaf__R_d_25__get(SEXP obj_SEXP) { @@ -1417,28 +1395,6 @@ BEGIN_RCPP return R_NilValue; END_RCPP } -// Leaf__rd_tracks_vcmax___get -bool Leaf__rd_tracks_vcmax___get(phylloptim::RcppR6::RcppR6 obj_); -RcppExport SEXP _phylloptim_Leaf__rd_tracks_vcmax___get(SEXP obj_SEXP) { -BEGIN_RCPP - Rcpp::RObject rcpp_result_gen; - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); - rcpp_result_gen = Rcpp::wrap(Leaf__rd_tracks_vcmax___get(obj_)); - return rcpp_result_gen; -END_RCPP -} -// Leaf__rd_tracks_vcmax___set -void Leaf__rd_tracks_vcmax___set(phylloptim::RcppR6::RcppR6 obj_, bool value); -RcppExport SEXP _phylloptim_Leaf__rd_tracks_vcmax___set(SEXP obj_SEXP, SEXP valueSEXP) { -BEGIN_RCPP - Rcpp::RNGScope rcpp_rngScope_gen; - Rcpp::traits::input_parameter< phylloptim::RcppR6::RcppR6 >::type obj_(obj_SEXP); - Rcpp::traits::input_parameter< bool >::type value(valueSEXP); - Leaf__rd_tracks_vcmax___set(obj_, value); - return R_NilValue; -END_RCPP -} // Leaf__PPFD___get double Leaf__PPFD___get(phylloptim::RcppR6::RcppR6 obj_); RcppExport SEXP _phylloptim_Leaf__PPFD___get(SEXP obj_SEXP) { @@ -2395,16 +2351,12 @@ static const R_CallMethodDef CallEntries[] = { {"_phylloptim_Leaf__ko_25___set", (DL_FUNC) &_phylloptim_Leaf__ko_25___set, 2}, {"_phylloptim_Leaf__ko_ha___get", (DL_FUNC) &_phylloptim_Leaf__ko_ha___get, 1}, {"_phylloptim_Leaf__ko_ha___set", (DL_FUNC) &_phylloptim_Leaf__ko_ha___set, 2}, - {"_phylloptim_Leaf__rd_to_vcmax_ratio___get", (DL_FUNC) &_phylloptim_Leaf__rd_to_vcmax_ratio___get, 1}, - {"_phylloptim_Leaf__rd_to_vcmax_ratio___set", (DL_FUNC) &_phylloptim_Leaf__rd_to_vcmax_ratio___set, 2}, {"_phylloptim_Leaf__R_d_25__get", (DL_FUNC) &_phylloptim_Leaf__R_d_25__get, 1}, {"_phylloptim_Leaf__R_d_25__set", (DL_FUNC) &_phylloptim_Leaf__R_d_25__set, 2}, {"_phylloptim_Leaf__rd_q10_intercept___get", (DL_FUNC) &_phylloptim_Leaf__rd_q10_intercept___get, 1}, {"_phylloptim_Leaf__rd_q10_intercept___set", (DL_FUNC) &_phylloptim_Leaf__rd_q10_intercept___set, 2}, {"_phylloptim_Leaf__rd_q10_slope___get", (DL_FUNC) &_phylloptim_Leaf__rd_q10_slope___get, 1}, {"_phylloptim_Leaf__rd_q10_slope___set", (DL_FUNC) &_phylloptim_Leaf__rd_q10_slope___set, 2}, - {"_phylloptim_Leaf__rd_tracks_vcmax___get", (DL_FUNC) &_phylloptim_Leaf__rd_tracks_vcmax___get, 1}, - {"_phylloptim_Leaf__rd_tracks_vcmax___set", (DL_FUNC) &_phylloptim_Leaf__rd_tracks_vcmax___set, 2}, {"_phylloptim_Leaf__PPFD___get", (DL_FUNC) &_phylloptim_Leaf__PPFD___get, 1}, {"_phylloptim_Leaf__PPFD___set", (DL_FUNC) &_phylloptim_Leaf__PPFD___set, 2}, {"_phylloptim_Leaf__atm_vpd___get", (DL_FUNC) &_phylloptim_Leaf__atm_vpd___get, 1}, diff --git a/src/RcppR6.cpp b/src/RcppR6.cpp index 4381f47..f83f997 100644 --- a/src/RcppR6.cpp +++ b/src/RcppR6.cpp @@ -491,15 +491,6 @@ void Leaf__ko_ha___set(phylloptim::RcppR6::RcppR6 obj_, double obj_->ko_ha_ = value; } -// [[Rcpp::export]] -double Leaf__rd_to_vcmax_ratio___get(phylloptim::RcppR6::RcppR6 obj_) { - return obj_->rd_to_vcmax_ratio_; -} -// [[Rcpp::export]] -void Leaf__rd_to_vcmax_ratio___set(phylloptim::RcppR6::RcppR6 obj_, double value) { - obj_->rd_to_vcmax_ratio_ = value; -} - // [[Rcpp::export]] double Leaf__R_d_25__get(phylloptim::RcppR6::RcppR6 obj_) { return obj_->R_d_25; @@ -527,15 +518,6 @@ void Leaf__rd_q10_slope___set(phylloptim::RcppR6::RcppR6 obj_, obj_->rd_q10_slope_ = value; } -// [[Rcpp::export]] -bool Leaf__rd_tracks_vcmax___get(phylloptim::RcppR6::RcppR6 obj_) { - return obj_->rd_tracks_vcmax_; -} -// [[Rcpp::export]] -void Leaf__rd_tracks_vcmax___set(phylloptim::RcppR6::RcppR6 obj_, bool value) { - obj_->rd_tracks_vcmax_ = value; -} - // [[Rcpp::export]] double Leaf__PPFD___get(phylloptim::RcppR6::RcppR6 obj_) { return obj_->PPFD_; diff --git a/tests/cpp/bench_gradient.cpp b/tests/cpp/bench_gradient.cpp index 4c1f3b5..3bb3838 100644 --- a/tests/cpp/bench_gradient.cpp +++ b/tests/cpp/bench_gradient.cpp @@ -49,7 +49,6 @@ #include #include #include -#include #include #include @@ -82,11 +81,10 @@ bool rebuilds_a_spline(int i) { } void apply_traits(phylloptim::Leaf &l, const Traits &t) { - // NaN for R_d_25: the sentinel meaning "derive from the ratio", so the benchmark - // keeps measuring the default configuration rather than a fixed respiration. + // R_d_25 last, at the class default, so the benchmark measures the default + // configuration. l.set_traits(t.v[0], t.v[1], t.v[2], t.v[3], t.v[4], t.v[5], t.v[6], t.v[7], - t.v[8], t.v[9], t.v[10], t.v[11], t.v[12], - std::numeric_limits::quiet_NaN()); + t.v[8], t.v[9], t.v[10], t.v[11], t.v[12], 1.44); } // One interior operating point. Drivers from plant's tests/testthat/test-leaf.r, diff --git a/tests/cpp/golden/operating_points.tsv b/tests/cpp/golden/operating_points.tsv index 80827b1..5941004 100644 --- a/tests/cpp/golden/operating_points.tsv +++ b/tests/cpp/golden/operating_points.tsv @@ -1,292 +1,4 @@ psi_soil ppfd vpd leaf_temp layers psi_stem opt_root_psi ci assim transpiration gc profit e_up uptake -0.5 100 0.5 15 1 1.4270758056424506 1.1539087272869564 31.257235861844791 4.7310032695803681 8.1422740244378988e-06 0.054816831797731273 4.6055059093498105 8.1422742472583521e-06 0.00045197192602044697 -0.5 100 0.5 15 3 1.6382590972862736 1.4348249852562254 28.230295773392683 4.5999669446863871 5.8807184865500825e-06 0.039591194690758266 4.3862388828625214 5.8807187044817758e-06 0.00032643456588852491 -0.5 100 0.5 15 5 1.8092061574112095 1.6399016990422024 25.818220790146675 4.4771996809175327 4.7502555347515307e-06 0.031980495603952969 4.1655864859055161 4.7502558929346261e-06 0.00026368336902218294 -0.5 100 1 15 1 1.6534087564262019 1.3076224186926617 26.509112703600671 4.5142766091578528 1.0069754354505595e-05 0.033896674874775656 4.2928910330016432 1.0069754353983692e-05 0.00055896499328246974 -0.5 100 1 15 3 1.894716996096661 1.6298036623668128 22.560885129586104 4.2774753295022139 7.3813245108427352e-06 0.024846917638790118 3.9068912074685311 7.3813251705680309e-06 0.00040973217710619099 -0.5 100 1 15 5 2.0802207176156107 1.8560597481402348 19.648799508188237 4.0544780925562778 5.9953721925450506e-06 0.020181543144897136 3.5309548684250642 5.9953725110573256e-06 0.00033279891818247713 -0.5 100 2 15 1 1.9325892590091942 1.4918873285332435 20.102575443843747 4.0926107633957276 1.2379548196607508e-05 0.020835936287227474 3.693642109478096 1.2379548221031022e-05 0.00068718002892206615 -0.5 100 2 15 3 2.1729776852103218 1.8351380028407198 15.57207868379745 3.636967641387896 8.9609518604227513e-06 0.015082119239848101 3.0234255918463013 8.960952741945347e-06 0.0004974161943905272 -0.5 100 2 15 5 2.3153969033468762 2.0385032803865486 12.585603664938979 3.2092841759936492 7.0458064228993806e-06 0.011858750528545165 2.4391838476658156 7.0458073543760129e-06 0.00039110781872750557 -0.5 100 4 15 1 2.1746421995595382 1.6456180690633588 12.757020672873406 3.2376910729776682 1.4305795818557067e-05 0.012038995506121326 2.6224484984617416 1.4305796682995104e-05 0.00079410472844824336 -0.5 100 4 15 3 2.2474806329827843 1.8887907875940946 8.8734068251374545 2.4238473397869176 9.3735670249438015e-06 0.0078882945570383344 1.7312095678767767 9.3735678741614365e-06 0.00052032017064454266 -0.5 100 4 15 5 2.212991014827272 1.9597232397272135 6.9074399553755033 1.812320523031588 6.5922832322856743e-06 0.0055477143120983797 1.1570586410770058 6.5922833967000929e-06 0.00036593302229809011 -0.5 500 0.5 15 1 2.2812766801752042 1.7112439794506997 25.895493275867921 14.180562817696165 1.5127835526573314e-05 0.10184624258960147 13.450021172560684 1.5127835678725456e-05 0.00083973553587152129 -0.5 500 0.5 15 3 2.6226804776277843 2.148626538732171 22.287437337211422 13.385528122418995 1.1370913070241663e-05 0.076553236514425943 12.200499671956257 1.1370913143347457e-05 0.00063119140401595656 -0.5 500 0.5 15 5 2.8865324870584814 2.4542168815024903 19.794311290504464 12.672949532703804 9.4372459955106754e-06 0.063535067085320168 11.050079291933642 9.4372462296323947e-06 0.00052385491144226446 -0.5 500 1 15 1 2.7317573418003795 1.9715476363885696 19.444846897667738 12.558929857536992 1.8386672598051978e-05 0.061892975850622402 11.201647883823473 1.8386673792684458e-05 0.0010206313512453209 -0.5 500 1 15 3 3.0593360403967864 2.4243233187446016 15.540165173989667 10.96319993961524 1.348823234808719e-05 0.045403910606217693 9.0168382199805688 1.3488233995280084e-05 0.00074872239773966602 -0.5 500 1 15 5 3.2175198979427253 2.6717407773019461 13.069724588938737 9.5638406857587199 1.0687171090925342e-05 0.035975014985157899 7.2996355028912667 1.0687172466261578e-05 0.00059323743914857497 -0.5 500 2 15 1 3.0011353940080516 2.1120305327183742 12.513033594957225 9.1996882650172864 2.0144083793065625e-05 0.033904375168708277 7.3652481430673165 2.0144085464812072e-05 0.0011181840391236233 -0.5 500 2 15 3 2.9940026353280822 2.3851817693762394 9.2954821111915891 6.7277888035007782 1.3187767645166625e-05 0.022196245134434897 4.9068642458020033 1.3187769329472031e-05 0.0007320438151247311 -0.5 500 2 15 5 2.9123807941675226 2.4719028017205904 7.5705037382454243 5.1397000921969447 9.5389109619065087e-06 0.016054878408752089 3.4701743966032068 9.5389119714930881e-06 0.00052949830538401819 -0.5 500 4 15 1 2.707878703300771 1.9585097680922661 7.3674492650304435 4.9402859396444905 1.822352049734454e-05 0.015335943847922856 3.6217954871462714 1.8223521505910895e-05 0.0010115748823708518 -0.5 500 4 15 3 2.5045282167856686 2.068825138898692 5.5882830256336185 3.0753370737872778 1.0757654614741469e-05 0.0090530689243641712 2.0623050119614508 1.0757655622419485e-05 0.0005971499096541485 -0.5 500 4 15 5 2.3515498387293619 2.0660504452236692 4.7417207180594687 2.1102108866857123 7.2043692020612226e-06 0.0060628132505250705 1.2967743142903365 7.2043694187172156e-06 0.00039990948757797479 -0.5 900 0.5 15 1 2.5011542191413296 1.8419429576531936 25.721619161415312 15.908445722653463 1.6764477309455815e-05 0.11286472674478223 14.900098293636528 1.6764478169952914e-05 0.00093058441132128306 -0.5 900 0.5 15 3 2.8553992925999241 2.2995869361644283 22.249799883344686 14.781959851834301 1.2530545937065702e-05 0.084360318371045559 13.214432054402785 1.2530547466595839e-05 0.00069556189101281369 -0.5 900 0.5 15 5 3.106151425262377 2.6007962159643574 19.822917113976946 13.784619918563667 1.0279633855997786e-05 0.069206336993232698 11.7461879700239 1.0279634008179982e-05 0.00057061526551096208 -0.5 900 1 15 1 2.930858516377512 2.0765846467471407 19.306769018992579 13.546905464881743 1.9700761736656422e-05 0.066316445452720335 11.843641502036018 1.9700763363384183e-05 0.0010935755405708679 -0.5 900 1 15 3 3.1767581276860066 2.4926309142076901 15.426922458200531 11.442027545119302 1.4012468901499191e-05 0.04716858880817687 9.2615065437143986 1.4012469162353296e-05 0.00077782232374983603 -0.5 900 1 15 5 3.2800412282439741 2.710498846183695 12.973142132875221 9.7980501253756547 1.090976317312951e-05 0.03672430152925299 7.4033204691431509 1.090976499376541e-05 0.0006055933940474832 -0.5 900 2 15 1 3.0450886417613527 2.1337507430139233 12.386797130368574 9.3665564262021199 2.0415705378407326e-05 0.034361539675565343 7.4478585288409356 2.041570607014201e-05 0.0011332615081955043 -0.5 900 2 15 3 3.0061089449125782 2.3924944271502917 9.2355240800259093 6.7696216180109285 1.3243906110355754e-05 0.022290731416596953 4.9257309267967191 1.3243907606735815e-05 0.00073516001147575991 -0.5 900 2 15 5 2.9174849870396038 2.4753820162221598 7.536207334410113 5.1559227091707402 9.5589097646129507e-06 0.0160885382622778 3.4771092947284128 9.5589110962128811e-06 0.00053060844275397618 -0.5 900 4 15 1 2.7117138516075068 1.9606099441737317 7.3335998046933133 4.9525425723291532 1.8249801891855117e-05 0.015358060869193146 3.6278622558269329 1.8249803093826081e-05 0.0010130337548612867 -0.5 900 4 15 3 2.5057182579900754 2.069638741676223 5.5730504189705474 3.0784867972264052 1.0763907750760056e-05 0.009058331230451978 2.0637993945339472 1.0763908802642431e-05 0.00059749701929738726 -0.5 900 4 15 5 2.3521204816617938 2.0664841010292712 4.7324852546661536 2.1114949209254075 7.2068652136032123e-06 0.0060649137608439901 1.297362582042668 7.2068654546686163e-06 0.00040004804078093903 -0.5 1500 0.5 15 1 2.5931813840435893 1.894634108786782 25.770296836572996 16.477998568401134 1.7424079678424497e-05 0.11730541641017796 15.3373513514981 1.7424080784876701e-05 0.00096719848930761597 -0.5 1500 0.5 15 3 2.9312814836170871 2.3468696653822798 22.290980821875223 15.174985138383267 1.2893623795594221e-05 0.086804694210117411 13.470945153103296 1.2893625416000684e-05 0.00071571609303362109 -0.5 1500 0.5 15 5 3.164443104122554 2.6382280651002139 19.844466696904352 14.057951861478927 1.0494674816796704e-05 0.07065407310999286 11.902481529149078 1.0494674960980749e-05 0.00058255203780076324 -0.5 1500 1 15 1 2.9794304417823492 2.1011766071129339 19.281530084223558 13.775188504193377 2.0008341691397746e-05 0.06735181705731165 11.981736411403519 2.0008342605845412e-05 0.0011106490483400173 -0.5 1500 1 15 3 3.1990865196290206 2.5053144981170208 15.395064332574272 11.53643495831383 1.4109792010341915e-05 0.047496196579141822 9.3102174479390243 1.4109793856289524e-05 0.00078322474916955453 -0.5 1500 1 15 5 3.2918796782386277 2.7177484504841605 12.947295105487171 9.8448459612333821 1.0951395266992813e-05 0.03686444293691396 7.4251234330926348 1.0951396234144393e-05 0.00060790431496777098 -0.5 1500 2 15 1 3.0533887316052439 2.1378131088771966 12.356198128922173 9.4002673387594911 2.0466503441633044e-05 0.034447037562247165 7.4654739411566133 2.0466504767205668e-05 0.0011360813081990378 -0.5 1500 2 15 3 3.0088258474321448 2.3941318307884547 9.2199650151853412 6.7794737636446403 1.3256476150605965e-05 0.022311887968808855 4.9304113893206667 1.3256477501527865e-05 0.00073585775750917932 -0.5 1500 2 15 5 2.9187607434288965 2.4762509370048669 7.5267842537144354 5.1601140783672648 9.5639043639490063e-06 0.016096944639626434 3.4789754417493657 9.5639057618451873e-06 0.00053088569313600815 -0.5 1500 4 15 1 2.7126825105121495 1.9611400221343682 7.3242895634782341 4.9557547253279761 1.8256435208450969e-05 0.015363643114997641 3.6295085552909487 1.8256436451373855e-05 0.0010134019678808689 -0.5 1500 4 15 3 2.5060518758617429 2.0698667932620811 5.5685727091965376 3.0793885487450132 1.0765660492889556e-05 0.0090598062448369234 2.0642368022500959 1.0765661556351781e-05 0.0005975943134250226 -0.5 1500 4 15 5 2.3522879976514237 2.0666113966729673 4.7296867094021682 2.1118771526419264 7.2075978939578894e-06 0.0060655303455911273 1.2975404975974949 7.2075981423254771e-06 0.00040008871175828349 -1 100 0.5 15 1 1.7391373156757322 1.5148805959302236 29.083208337785024 4.6392354746567932 6.3942943248732606e-06 0.043048779176400029 4.3708562950048675 6.3942946253795099e-06 0.00035494280462833804 -1 100 0.5 15 3 1.9663652446680653 1.7912730104765946 25.873640002657417 4.4802347179575639 4.7721240637324448e-06 0.032127722714120552 4.0547442943665803 4.7721247693795351e-06 0.00026489729499747626 -1 100 0.5 15 5 2.1493766096015383 1.9987318750952885 23.419602326966462 4.334550329729657 3.9336012709276583e-06 0.026482473886362382 3.7447948502697153 3.9336016222502949e-06 0.00021835146390509547 -1 100 1 15 1 1.9625941269612672 1.6634580180143912 24.054181941278785 4.3745703400345723 8.255812547066679e-06 0.027790607782780669 3.9520981815617393 8.2558132605759833e-06 0.00045827439692345173 -1 100 1 15 3 2.2142240386119907 1.9758626636900083 20.106654054020098 4.09294729029107 6.191552226196622e-06 0.020841921797990541 3.4363718479133434 6.1915524359509297e-06 0.00034368872805722619 -1 100 1 15 5 2.4034029878288918 2.1971967588181878 17.286379673076585 3.8310262891470988 5.0757473215598434e-06 0.01708591398045824 2.9528751262888613 5.0757475116756947e-06 0.00028175118022068804 -1 100 2 15 1 2.228488461384492 1.8341283174600069 17.617053881018201 3.8650955313467961 1.0393078388542529e-05 0.017492521996172381 3.1932020093233184 1.0393079164705849e-05 0.00057691252648936161 -1 100 2 15 3 2.4510618263991666 2.1463507880767829 13.313480995154798 3.3262718077709166 7.5018266859076992e-06 0.012626275239045493 2.3859798990081789 7.5018277886214506e-06 0.00041642119281828758 -1 100 2 15 5 2.5634858382205641 2.3187873487996264 10.5541551428289 2.8254320973599629 5.7751341188561837e-06 0.0097200903166770134 1.7284986292395095 5.7751346627426384e-06 0.00032057366987191997 -1 100 4 15 1 2.3950199136627663 1.9369559267188385 10.656958979033064 2.847226212578283 1.1680140522739637e-05 0.0098293839117795569 1.979741911040354 1.1680141100512984e-05 0.00064835643078062634 -1 100 4 15 3 2.3929428651528819 2.1051158612162881 7.3050430037279215 1.9515316081728571 7.1849877916382538e-06 0.0060465028882115152 1.0866780094483011 7.1849884664530721e-06 0.00039883366452695378 -1 100 4 15 5 2.311168530955749 2.1258596465263766 5.7042781426882172 1.3291900540974999 4.665286827366998e-06 0.0039260568137413372 0.56406266647418668 4.6652878309307411e-06 0.00025896685156429316 -1 500 0.5 15 1 2.6022141805996126 2.0598056108659679 24.239652930171516 13.843989659857463 1.3217116478726718e-05 0.088982567853997274 12.689853607231102 1.3217117139603216e-05 0.00073367289145729762 -1 500 0.5 15 3 2.9647052441022557 2.4901518382672272 20.759138413492344 12.968427085232411 1.0141542556488343e-05 0.068276654755172472 11.202543232756259 1.0141542571319255e-05 0.00056294990681761057 -1 500 0.5 15 5 3.2422039682132207 2.7938491449058871 18.416306480804607 12.199280178236247 8.5045172911219319e-06 0.057255588852588586 9.8838456491509685 8.5045173669822721e-06 0.00047207978723187743 -1 500 1 15 1 3.0534532263740797 2.3044498911669811 17.844399244674058 11.982319369344291 1.6275284320459045e-05 0.054785648356783644 10.047400678394236 1.6275285650329859e-05 0.00090342967806438293 -1 500 1 15 3 3.355567547728127 2.7213978136079584 14.166864055840524 10.228002137736871 1.1914749188370317e-05 0.040107272256545035 7.6724242014919852 1.1914750638474726e-05 0.00066137944149179714 -1 500 1 15 5 3.4809735729825024 2.941197430212307 11.854251308574554 8.7447420050102007 9.349866703220548e-06 0.031473398516394899 5.9156429118633014 9.3498688732681487e-06 0.0005190046557462198 -1 500 2 15 1 3.2062007927591365 2.3792181203040257 11.168928956580078 8.2436393809298405 1.7209150338001184e-05 0.028964607940875745 6.0027884559215421 1.720915224439736e-05 0.00095526795694684218 -1 500 2 15 3 3.1433548913274634 2.5995162221945929 8.2542388752773483 5.7916600693371514 1.0980409564046137e-05 0.018481055241323374 3.6788277197708479 1.0980411210241696e-05 0.00060951491591683025 -1 500 2 15 5 3.0314700745370935 2.6544613750311488 6.6972978185179599 4.2629452671770967 7.7042701458774267e-06 0.012967006497303452 2.370530820630167 7.7042701454306829e-06 0.00042765862589123969 -1 500 4 15 1 2.7992609213577193 2.17076533098657 6.5056873262118255 4.0637788317123951 1.4604618228348951e-05 0.012290468524067398 2.5936316161967219 1.4604619544089053e-05 0.00081069217563636158 -1 500 4 15 3 2.5666126847989426 2.2270557678987348 4.9601068405159641 2.3642004340303959 8.1218083021170648e-06 0.0068348811132849293 1.2627097622339418 8.1218090257800698e-06 0.00045083591594671497 -1 500 4 15 5 2.3978981911160466 2.1929641681699308 4.230049450982607 1.5010617382583473 5.0513961688353355e-06 0.0042509858624824809 0.62992392653478402 5.0513966079508069e-06 0.0002803994786539443 -1 900 0.5 15 1 2.8248308157533688 2.1847111857099675 24.250315377279428 15.469431438428687 1.4778954718447882e-05 0.099497446599799519 13.955318822846607 1.4778954717710948e-05 0.0008203693987072411 -1 900 0.5 15 3 3.191216647174977 2.6277924976468858 20.867672506384864 14.237608895573688 1.1197226951642876e-05 0.075383916651172181 12.027537851879298 1.1197228380739941e-05 0.0006215502848037714 -1 900 0.5 15 5 3.4474423227596223 2.921231671106995 18.536019949352667 13.174159561625679 9.2353613237811983e-06 0.062175904023561261 10.418884349272156 9.2353613514293667e-06 0.00051264842361528542 -1 900 1 15 1 3.2264507801789923 2.3888012770097968 17.787058110766125 12.790979594713299 1.7328818363227902e-05 0.058332040816820689 10.508286207115271 1.7328819003319852e-05 0.00096191057470551491 -1 900 1 15 3 3.4441124178165867 2.769495752835077 14.087872991456999 10.576620610913803 1.2283300778866756e-05 0.041347885780751763 7.8286513149902888 1.2283300787527436e-05 0.00068183740147251932 -1 900 1 15 5 3.5255415481140506 2.9673514552981457 11.784461992537459 8.9070474944520281 9.4998479947917618e-06 0.031978263570567114 5.9791629562089756 9.4998486741495515e-06 0.00052732992917843753 -1 900 2 15 1 3.2341882136622813 2.3924422719683998 11.080224574116347 8.3483488315326291 1.7374282990180815e-05 0.029242541623520042 6.0495946255209603 1.7374283098410003e-05 0.00096443425469941728 -1 900 2 15 3 3.1511358186388074 2.6041434209007082 8.2129573482224174 5.8179314663000827 1.1015892673603013e-05 0.018540776630041129 3.6894054160808607 1.101589381152013e-05 0.00061148453019817543 -1 900 2 15 5 3.0347663382225534 2.6567037336376291 6.6737927197978983 4.2730846615985794 7.7171479396993813e-06 0.012988681027531286 2.3743229267206418 7.7171479839973968e-06 0.00042837346566735479 -1 900 4 15 1 2.8016722162596914 2.1720850424213833 6.4825950957763236 4.0711743764056418 1.4621116374947054e-05 0.012304352485174702 2.5969092432350735 1.4621117580119191e-05 0.00081160797003159541 -1 900 4 15 3 2.5673708841130631 2.2275794580212356 4.9496612366715009 2.3660764491539128 8.1258306736377827e-06 0.0068382661268330093 1.2634791203832965 8.1258314397414245e-06 0.00045105919732120036 -1 900 4 15 5 2.3982541568618814 2.1932379656102254 4.2237867712950798 1.5017927230491708 5.0529714050799642e-06 0.0042523114973727506 0.63020242398306625 5.0529718270626416e-06 0.00028048691796073502 -1 1500 0.5 15 1 2.9105586467347213 2.2306705747216835 24.339385614815612 15.979829568633408 1.5353400377651809e-05 0.10336482946888594 14.31361355807347 1.5353401256896362e-05 0.00085225652272530458 -1 1500 0.5 15 3 3.2580399229224772 2.6665142772483632 20.923395465831724 14.572509735433876 1.1494087678994574e-05 0.077382494015401024 12.223998570275747 1.1494088994973954e-05 0.00063802880904656977 -1 1500 0.5 15 5 3.4974067674841236 2.9508922340329891 18.56328999906232 13.39976462910983 9.4054648642200367e-06 0.063321104631701958 10.534324577115152 9.4054660358551981e-06 0.00052209081520150971 -1 1500 1 15 1 3.2643363351400967 2.4065194635867031 17.768863411191603 12.964889208119915 1.7550050349641567e-05 0.059076749024326213 10.603182074890173 1.7550052101271061e-05 0.00097419106862453846 -1 1500 1 15 3 3.4607785023811162 2.7783603462896931 14.063347394364417 10.645163715644083 1.23512139227837e-05 0.041576494113987464 7.8605817180238748 1.2351214987919876e-05 0.00068560727104745355 -1 1500 1 15 5 3.5343857166066264 2.9724889349299346 11.765122684399877 8.9407906745055516 9.5293054079935097e-06 0.03207742272805985 5.9932212164473029 9.5293069535330765e-06 0.00052896513758163071 -1 1500 2 15 1 3.239823461039486 2.3950868304150985 11.057835364565207 8.3706910487029358 1.7407304362316228e-05 0.029298119678147178 6.0602146259953038 1.740730436955627e-05 0.00096626724227345372 -1 1500 2 15 3 3.1530013923509541 2.60525110910796 8.2018016676096632 5.8244609074436786 1.1024386750984807e-05 0.018555072955911436 3.6921653815670714 1.1024387740012799e-05 0.00061195602220442957 -1 1500 2 15 5 3.0356352754361327 2.6572945334547073 6.667111569777278 4.2758203900431164 7.7205408441283775e-06 0.012994391602698368 2.3753838915495304 7.7205409185726294e-06 0.00042856180508313237 -1 1500 4 15 1 2.8023138432586112 2.1724360470203954 6.47602003656527 4.0731950709056619 1.462550438456759e-05 0.012308045200265317 2.5978332013702019 1.462550555678395e-05 0.00081185154353505132 -1 1500 4 15 3 2.5675909200632425 2.2277314226562406 4.9465179632589766 2.3666285350348377 8.1269978858496521e-06 0.0068392483904380266 1.2637099262758491 8.1269986641282252e-06 0.00045112398912729537 -1 1500 4 15 5 2.3983614986301434 2.193320526789325 4.2218541830580101 1.5020150298432391 5.053446403253614e-06 0.0042527112305263985 0.63028825493130103 5.0534468200808321e-06 0.0002805132844896382 -2 100 0.5 15 1 2.525142687932648 2.3452619975210345 24.442536959303006 4.3982151146015624 4.2538181212338741e-06 0.028638293399357327 3.3562855837459353 4.2538191360249271e-06 0.00023612651324035123 -2 100 0.5 15 3 2.7672160413894638 2.6115220260059111 21.334848497644259 4.1895690221878521 3.3773732445269163e-06 0.022737738929901809 2.7735852252668796 3.377373678869224e-06 0.00018747564134716758 -2 100 0.5 15 5 2.9630880586088653 2.8190188386199369 19.116260422780233 4.0079069939280254 2.8876901686453258e-06 0.01944100945061486 2.245038898083072 2.8876901672958232e-06 0.00016029365347187472 -2 100 1 15 1 2.7265846282440953 2.4682924163642235 19.150586947977391 4.0109704516983573 5.7893106379097305e-06 0.019487901445629764 2.6621424991178246 5.7893120099905826e-06 0.0003213606444624248 -2 100 1 15 3 2.977848889359179 2.7562288344127097 15.588599240424038 3.6389908974839669 4.4860023073291866e-06 0.015100722057931146 1.8485090848340509 4.4860031004616564e-06 0.00024901488206836836 -2 100 1 15 5 3.1587919078052744 2.9602440790483309 13.142982445426792 3.299703383996071 3.6973310930309707e-06 0.012445907372983086 1.1556914243639436 3.6973316118984789e-06 0.00020523628153752311 -2 100 2 15 1 2.9232267664770362 2.5825294563468235 12.854513183603807 3.2536060843082462 7.2138740677320183e-06 0.012141624078052964 1.564315560321424 7.2138756395075649e-06 0.00040043717121884901 -2 100 2 15 3 3.0605506297892089 2.8110945804056522 9.2041469196786281 2.5102952101004825 4.9060704235877675e-06 0.0082573749173284784 0.56156734209983639 4.9060721149250919e-06 0.00027233261809187301 -2 100 2 15 5 3.0734167016868374 2.8993973185666313 6.9768871813912039 1.8372917016161776 3.3485849795245483e-06 0.0056359813926699217 -0.13657523732736299 3.3485866100120824e-06 0.00018587769136897488 -2 100 4 15 1 2.8273949614561333 2.5276257583835253 6.8659699832141285 1.7972719534627117 6.5293620556539575e-06 0.005494763202470037 0.27871435056325655 6.5293620793477391e-06 0.00036244030415474545 -2 100 4 15 3 2.6524189613564046 2.5299357359865544 4.6486258811614896 0.80817894762280085 2.7518987367911342e-06 0.0023158513476442886 -0.42254852983125557 2.7519000961961459e-06 0.00015275604197591706 -2 100 4 15 5 2.4824438870701759 2.449687103805104 3.6945824454223608 0.2314077099629217 7.6725124843155325e-07 0.00064567776928226245 -0.75119176855868564 7.6725126109849867e-07 4.2589578745406533e-05 -2 500 0.5 15 1 3.4075446695161782 2.8349533535174736 21.041275656123162 13.049857141754579 1.0357092944514989e-05 0.069727820526421236 10.381796328822858 1.0357095026694429e-05 0.00057491507225614373 -2 500 0.5 15 3 3.8167263355846548 3.2499539728449225 18.036837097899902 12.056764090451692 8.2599441117891881e-06 0.055609030803389928 8.4721934125114942 8.2599463293360096e-06 0.00045850382066811042 -2 500 0.5 15 5 4.1333329692832042 3.5474349378045025 16.069809603382748 11.219883745318331 7.0547792886099722e-06 0.047495410799632022 6.9248402613338973 7.0547792957860616e-06 0.00039160584489514636 -2 500 1 15 1 3.824223205086315 3.0145323734764879 14.760327623176723 10.558439189455928 1.2588884054298436e-05 0.042376536189670813 6.9568616233759979 1.2588886488004642e-05 0.00069880024912598619 -2 500 1 15 3 4.0459447946540861 3.3571380448258372 11.604126740317742 8.5651498476849337 9.0771802636351885e-06 0.03055548500430914 4.463742386087926 9.0771819167318646e-06 0.0005038679942676583 -2 500 1 15 5 4.110401336582461 3.5362706447429346 9.6681775245732844 7.0464855495891205 6.9910962939892361e-06 0.023533336539591998 2.8019892764784009 6.9910983865649597e-06 0.00038807096234054733 -2 500 2 15 1 3.6545904945051935 2.9458679988783034 8.6115273537722103 6.1205277392456559 1.1735994750526898e-05 0.019752775707616348 2.9032755151767828 1.1735994793927943e-05 0.00065145683008203958 -2 500 2 15 3 3.4842026238783079 3.0720836915941003 6.3148153064897041 3.862908979826571 6.9020287158206185e-06 0.011616759213786384 1.026677091690217 6.9020308149831811e-06 0.00038312688398463399 -2 500 2 15 5 3.3064878295435691 3.0624776162175102 5.0658848899920734 2.4859558169679041 4.2829684800382041e-06 0.007208636127345484 0.035277232782320311 4.2829684853976187e-06 0.00023774457315557142 -2 500 4 15 1 3.0026720112487855 2.6268796215017147 4.8755334231116914 2.2662590861494811 7.7666017463108896e-06 0.0065359582023659683 0.42890144656987861 7.7666033776222323e-06 0.00043111869984025712 -2 500 4 15 3 2.7055400303625561 2.5679107956794462 3.7541319560016442 0.9163025659328915 3.0430676901818512e-06 0.0025608836244817514 -0.39842093188341055 3.0430685614353892e-06 0.0001689185990250008 -2 500 4 15 5 2.5001554684080762 2.4637610623687634 3.2359914026099621 0.25903085275413218 8.481249736982093e-07 0.00071373678727730398 -0.74793229293176944 8.4812578544605943e-07 4.707886680244571e-05 -2 900 0.5 15 1 3.6333885859624502 2.9368521841362059 21.327108253283917 14.425290500774357 1.1623962940075393e-05 0.078256862812126113 11.255848154387289 1.162396435089127e-05 0.00064523809885602386 -2 900 0.5 15 3 4.0308562427518879 3.3504839851280881 18.265758652377009 13.038305282683179 9.026468863432208e-06 0.060769561909749227 8.9705855811591597 9.0264714049048403e-06 0.0005010530893646872 -2 900 0.5 15 5 4.3179908366497166 3.632167908615239 16.213634584616408 11.916140661019549 7.5378720778801313e-06 0.050747772006419993 7.2227930700060163 7.5378741319444999e-06 0.00041842210002467387 -2 900 1 15 1 3.9357527330052142 3.056291156482005 14.735072271458936 11.004228102969993 1.3107285155213868e-05 0.044121571168065685 7.1501716072381623 1.3107285587935153e-05 0.00072757621914710819 -2 900 1 15 3 4.0927527027585517 3.3774168881653552 11.55358394150041 8.7264623326305131 9.2317042870088719e-06 0.031075641742620869 4.521002801677831 9.2317066535861107e-06 0.0005124455539043081 -2 900 1 15 5 4.1338229965314879 3.5476719741394849 9.6293029499284106 7.1211508830585393 7.0561312740221734e-06 0.023752256435356649 2.8250294963752474 7.0561312741898521e-06 0.00039168089226699151 -2 900 2 15 1 3.665054385462688 2.9502823558273943 8.5704715798881175 6.1571750829788616 1.1790843038605897e-05 0.019845090501155477 2.9162975814714129 1.1790843927069033e-05 0.00065450146694804516 -2 900 2 15 3 3.4872861688076675 3.0738486023394187 6.2966056814819602 3.8725479649231875 6.9155127068975807e-06 0.011639454030633909 1.0295009845399448 6.9155146713765498e-06 0.00038387536338476547 -2 900 2 15 5 3.3077514015313452 3.0633347759331206 5.0559991900680537 2.4895090963074775 4.2878769149947182e-06 0.0072168974819926558 0.036146967243160688 4.2878769133959554e-06 0.00023801703654709717 -2 900 4 15 1 3.0034992218289829 2.6273356838813786 4.8661043742768424 2.2685261311224387 7.7722845968109135e-06 0.0065407405865478396 0.42959704209995642 7.7722862011103806e-06 0.00043143414938164753 -2 900 4 15 3 2.7057690948054285 2.5680737353133938 3.7502108427057248 0.9167778720479699 3.0443168585655522e-06 0.0025619348580341174 -0.39831432982119319 3.044317743753102e-06 0.00016898794025829042 -2 900 4 15 5 2.5002334749370285 2.4638229807833447 3.2339752866254896 0.25915372843944806 8.4848076602247031e-07 0.00071403620313974291 -0.7479174954186123 8.4848158164864555e-07 4.7098616799813795e-05 -2 1500 0.5 15 1 3.705258224812205 2.9670251600066964 21.435182102180214 14.804345177847452 1.1998853123071474e-05 0.080780763634210717 11.472545274976728 1.1998854264812507e-05 0.00066604797473286193 -2 1500 0.5 15 3 4.083683328319907 3.3735306944554537 18.311346783499751 13.264108091676784 9.2020946466088208e-06 0.061951940319864431 9.0787523067866083 9.2020962208696282e-06 0.00051080189957644346 -2 1500 0.5 15 5 4.3577195071163741 3.649187205603031 16.229624775536518 12.061346366224997 7.6348582847019432e-06 0.051400719398032528 7.2847039977162567 7.6348597158625362e-06 0.00042380570168540306 -2 1500 1 15 1 3.9573686641488242 3.0640729167681053 14.718968355224144 11.092374875297409 1.3203861801434383e-05 0.044446666206354103 7.1895812630719131 1.3203864227276875e-05 0.00073293723160015964 -2 1500 1 15 3 4.1022456020180522 3.3814623689925423 11.53820545248713 8.7603315614280994 9.2625270275068617e-06 0.031179396846929098 4.5338607208272377 9.2625295662028201e-06 0.00051415651214004 -2 1500 1 15 5 4.139014414091716 3.5501792288199265 9.6180886556183118 7.1382176731964959 7.0704314990657739e-06 0.023800393665111632 2.830682751358915 7.0704316576894154e-06 0.00039247469651342855 -2 1500 2 15 1 3.6675192133967012 2.9513187830472969 8.5593071616572338 6.1660890854605075 1.1803720214748902e-05 0.019866763991771924 2.9196439139851522 1.1803721363765144e-05 0.00065521628441660531 -2 1500 2 15 3 3.4881178855929833 3.0743242911345741 6.2913226440665273 3.8751904214605446 6.9191469663212473e-06 0.011645570828807815 1.0303046071180932 6.9191488840989447e-06 0.00038407709598106828 -2 1500 2 15 5 3.3081164227664295 3.0635823357475953 5.0530183639424493 2.4905445860881965 4.2892945308694539e-06 0.0072192834619635446 0.036407059774692829 4.2892945311054077e-06 0.00023809572751070819 -2 1500 4 15 1 3.0037404878733098 2.6274686774930611 4.8632525420259372 2.2691939974501745 7.773941785374284e-06 0.0065421351881429033 0.42980646333212769 7.7739433811225097e-06 0.00043152613828046125 -2 1500 4 15 3 2.7058398922139593 2.5681240939587924 3.7489805014375754 0.91692525504798972 3.0447029303327146e-06 0.002562259755462325 -0.3982809141462077 3.0447038198083056e-06 0.00016900937106901503 -2 1500 4 15 5 2.5002582342138409 2.463842633567924 3.2333321211941382 0.25919275437049105 8.4859369379675456e-07 0.00071413123713745736 -0.7479127749239618 8.4859451065152811e-07 4.7104885409465894e-05 -3 100 0.5 15 1 3.4675059500349152 3.2655675612116877 20.701416604354947 4.1408840402186362 3.2285600321368866e-06 0.021735872767158972 1.3414904173667415 3.2285617051243442e-06 0.00017921519317925863 -3 100 0.5 15 3 3.7213245705181697 3.5259960756746507 18.137754813634984 3.916781288102869 2.695726258140796e-06 0.018148636661173154 0.54859246226082226 2.6957262563139272e-06 0.00014963787156891076 -3 100 0.5 15 5 3.9328379175845596 3.7353891501423706 16.410029751640007 3.7356800630296485 2.3827776054080902e-06 0.016041749370633993 -0.1117979952546504 2.3827777957409585e-06 0.00013226632227260386 -3 100 1 15 1 3.6532452896296452 3.3579740538416134 15.239883014080174 3.5955880715795949 4.3700706945340633e-06 0.0147104745853236 0.3813716938222238 4.3700707019132974e-06 0.00024257955603182335 -3 100 1 15 3 3.897273076672755 3.6250436309311569 12.343209736836197 3.1681651097997836 3.4472855154723874e-06 0.011604207233338026 -0.59893981072275126 3.4472879120503534e-06 0.0001913565313377937 -3 100 1 15 5 4.0698281505124267 3.8162029569007916 10.408789433937148 2.794123806386501 2.8415423765373232e-06 0.0095651626335141182 -1.3604653066527956 2.841542515828344e-06 0.00015773202974345512 -3 100 2 15 1 3.7182980230585718 3.388533929695174 8.9640562335593774 2.4479434866537519 4.7472013307939329e-06 0.0079899833903607099 -0.91338852785138203 4.7472013805505235e-06 0.0002635138151845975 -3 100 2 15 3 3.7144363678821359 3.5219643114996724 6.1036308864486184 1.5009533373240185 2.6651105601870116e-06 0.004485630085085914 -1.8516311369831313 2.6651108296439376e-06 0.00014793843073238622 -3 100 2 15 5 3.5950521250353913 3.5160748032929483 4.4043676682664197 0.67136268429137502 1.1351720929852943e-06 0.0019106006963131299 -2.4118672999064477 1.1351728497907589e-06 6.3012647781890587e-05 -3 100 4 15 1 3.21236351564652 3.1268512086383211 4.0364805831426525 0.45171383487374761 1.5119325670575711e-06 0.0012723618882322697 -1.8018415131550225 1.5119342683199617e-06 8.392640956536007e-05 -3 100 4 15 3 3.1718079687688916 3.1718075251234743 3.361472054878722 2.3849817223364767e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704360025386209 7.8605668043621887e-12 4.3633454367816762e-10 -3 100 4 15 5 3.3170442487608387 3.3170439012574113 3.3614711552711181 1.7359976419717427e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731248171258904 6.1738007589111003e-12 3.4270334492984183e-10 -3 500 0.5 15 1 4.5233153883223345 3.6857390035850806 18.261414529211986 12.141781869867932 8.404122487948054e-06 0.056579693516416972 7.029115987125075 8.4041246620918214e-06 0.00046650705867842471 -3 500 0.5 15 3 5.0613513411139843 4.0744568571108513 15.708138102536267 11.046160092976326 6.842136877292937e-06 0.046063822614409458 4.9971447150038584 6.8421392545679343e-06 0.00037980234552139518 -3 500 0.5 15 5 5.5113326370152791 4.3455981531473551 13.943894147527715 10.098690503973073 5.831721570913922e-06 0.03926132914275856 3.4770634727564156 5.8317215753768378e-06 0.00032371476965733213 -3 500 1 15 1 4.8243773632812736 3.7595552343116583 11.816887665077143 8.7181548951546155 9.3090819402778307e-06 0.031336109382951886 3.0493716779096705 9.3090819414374222e-06 0.00051674060180057857 -3 500 1 15 3 4.9611330431564342 4.0495630596983805 9.3527297974547139 6.7772994300846072 6.6548167394079218e-06 0.022401356718894889 0.88256000009754754 6.6548167350140155e-06 0.00036940420399744745 -3 500 1 15 5 4.9942011377429347 4.2214588144844711 7.9158039199645067 5.4726917467549798 5.1331156484331879e-06 0.017279026489033539 -0.47402356283799296 5.1331180956487393e-06 0.00028493578105183123 -3 500 2 15 1 4.189977698575893 3.5809006140901309 6.4170902149025277 3.9708491012453919 7.1164971580711732e-06 0.011977729640766753 -0.44812748861500395 7.1164981435834093e-06 0.00039503181479785788 -3 500 2 15 3 3.9246207412129417 3.6397404342376691 4.7210334080960914 2.0859667552108112 3.5587112162921687e-06 0.0059896434821123156 -1.7429583339245238 3.558711285133102e-06 0.00019754156453694711 -3 500 2 15 5 3.67278686331694 3.5689024416460375 3.7136772057821497 0.86576866414733311 1.4360187905067759e-06 0.0024169537975917521 -2.3925784992230739 1.4360204651361094e-06 7.9712487656736578e-05 -3 500 4 15 1 3.2492554414548276 3.1477078667798191 3.4533854087052238 0.53746816193279268 1.7702589744096627e-06 0.0014897556282708422 -1.7926748163683088 1.7702595223886227e-06 9.8265863024625188e-05 -3 500 4 15 3 3.1718079687688916 3.1718075251234743 3.0364502642382956 2.4061391576957192e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704359813811855 7.8605668043621887e-12 4.3633454367816762e-10 -3 500 4 15 5 3.3170442487608387 3.3170439012574113 3.0364497630968215 1.7513978942673702e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731248017256382 6.1738007589111003e-12 3.4270334492984183e-10 -3 900 0.5 15 1 4.7830454904970701 3.7505218159742624 18.488526819932964 13.15048165325415 9.1984093884098357e-06 0.06192712978435326 7.5534024823654349 9.1984118144250468e-06 0.00051059738076186768 -3 900 0.5 15 3 5.2957485726770193 4.1239449641980546 15.738106189792939 11.632548875510979 7.2142537957635027e-06 0.048569052783238031 5.2608639363111429 7.2142543259646976e-06 0.00040045819183817362 -3 900 0.5 15 5 5.6993736816803677 4.3760742730709916 13.866332410999906 10.426168184419446 6.0029619665760911e-06 0.040414183485147026 3.621557660825558 6.0029631706554214e-06 0.00033322027036666228 -3 900 1 15 1 4.8857520459338986 3.7723555504097028 11.755283102677973 8.8843622226021157 9.4658638720812843e-06 0.031863866662969649 3.1120013171105549 9.4658641620661462e-06 0.00052544347277636114 -3 900 1 15 3 4.986498464540281 4.0560864256889495 9.3100758793779743 6.8367992375735307 6.7039109422180275e-06 0.02256661697970213 0.9020970421147938 6.703913087266247e-06 0.00037212950803587272 -3 900 1 15 5 5.0083783866987979 4.2257605423855811 7.887962647203473 5.5033037632648867 5.1573528870845795e-06 0.01736061356350482 -0.46537303493798721 5.1573546784875336e-06 0.00028628113674646316 -3 900 2 15 1 4.1938384286832209 3.5822607532676103 6.3991285376168143 3.9823087821755996 7.1332198566381756e-06 0.01200587550492584 -0.44506323590998509 7.1332204236287253e-06 0.00039596005682091174 -3 900 2 15 3 3.9258025124022118 3.6403712002137163 4.713609895514657 2.0892090636489646 3.5634928336890372e-06 0.0059976913909575149 -1.7423849401611493 3.563492859557226e-06 0.00019780698637564397 -3 900 2 15 5 3.6731764568983092 3.5691638373349366 3.7103462447068285 0.86674538002293111 1.4375068748390625e-06 0.0024194583825608578 -2.3924822186815056 1.4375085846159594e-06 7.979509212411654e-05 -3 900 4 15 1 3.2494246140397451 3.1478029063998392 3.4507355301478118 0.53786449057585373 1.7714359216639437e-06 0.001490746084368842 -1.7926317557562421 1.7714364839793164e-06 9.833119533607085e-05 -3 900 4 15 3 3.1718079687688916 3.1718075251234743 3.035037789744063 2.4062309841310636e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.170435981289359 7.8605668043621887e-12 4.3633454367816762e-10 -3 900 4 15 5 3.3170442487608387 3.3170439012574113 3.0350372902455511 1.7514647028260555e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731248016588294 6.1738007589111003e-12 3.4270334492984183e-10 -3 1500 0.5 15 1 4.8503119343661529 3.7650527929845907 18.527558927972681 13.380652066959453 9.3764207374680093e-06 0.063125568715556246 7.6676748149780209 9.3764230501145096e-06 0.00052047865945681435 -3 1500 0.5 15 3 5.3448749431036049 4.1328739144378144 15.7250937538633 11.747037292704889 7.2813517981537137e-06 0.049020781612303312 5.3144993825427589 7.281353890599832e-06 0.00040418284155425104 -3 1500 0.5 15 5 5.7354799405310777 4.3811764890211728 13.83774169177347 10.487404192469432 6.0316204547505422e-06 0.040607123138261265 3.6512042723756286 6.0316214210793099e-06 0.00033481106972408048 -3 1500 1 15 1 4.8979802953717009 3.7748198281710126 11.736915464891027 8.9184825891060555 9.4960421846167416e-06 0.031965452502332854 3.1259044785997609 9.4960424078746162e-06 0.00052711864601024793 -3 1500 1 15 3 4.9922797722033589 4.0575518897007701 9.2982791566781184 6.8506784088249075 6.7149392244076726e-06 0.022603740238388417 0.90695432255944208 6.7149416405486878e-06 0.00037274169528441229 -3 1500 1 15 5 5.0118606372352863 4.2268087877760943 7.8800238523951078 5.5109680409989377 5.1632588999151931e-06 0.017380494306339027 -0.46307333149057861 5.163260349313798e-06 0.00028660895638711061 -3 1500 2 15 1 4.1948741098562703 3.5826250346287258 6.393905852580577 3.9854285046222042 7.1376985543124085e-06 0.012013413571574804 -0.44419450284494477 7.1376990195124433e-06 0.00039620866053357998 -3 1500 2 15 3 3.9261503862909959 3.6405568082676982 4.7113395521190267 2.0901684456138403 3.5648998514927512e-06 0.0060000595333846518 -1.7422111546226433 3.5648998682008568e-06 0.00019788508843746083 -3 1500 2 15 5 3.6732972276007945 3.5692448608372125 3.7092972122047678 0.86704855599874764 1.437968127954547e-06 0.0024202347146510027 -2.3924519748113302 1.4379698484874761e-06 7.9820696557728345e-05 -3 1500 4 15 1 3.2494777219426689 3.1478327407973268 3.4498954765414069 0.53798903580896151 1.7718053831514009e-06 0.0014910570034706941 -1.7926181148371687 1.7718059499836263e-06 9.8351704134533796e-05 -3 1500 4 15 3 3.1718079687688916 3.1718075251234743 3.034584392545618 2.4062604880858984e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.170435981259855 7.8605668043621887e-12 4.3633454367816762e-10 -3 1500 4 15 5 3.3170442487608387 3.3170439012574113 3.0345838935670546 1.7514861749834409e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731248016373577 6.1738007589111003e-12 3.4270334492984183e-10 -4 100 0.5 15 1 4.5760023535758432 4.2301288559861678 18.272027683013093 3.9297366422365503 2.7213567313139148e-06 0.018321190585618617 -1.2856693341753944 2.7213591949513712e-06 0.000151060737993415 -4 100 0.5 15 3 4.8831975005619492 4.4933288951145611 16.412886593520792 3.7360034795531742 2.3832725184429959e-06 0.016045081310152056 -2.0321162279041234 2.3832730335537004e-06 0.00013229381257583682 -4 100 0.5 15 5 5.1641725268402734 4.710669130176659 15.192803149832063 3.5896142689422321 2.1772651353473472e-06 0.014658162614668267 -2.607545283309749 2.1772652306823216e-06 0.00012085846409560486 -4 100 1 15 1 4.7930752748449068 4.2939090471049015 12.471948108458609 3.1901447672897252 3.4874351236338232e-06 0.011739358317096977 -2.424476951935989 3.4874375904732738e-06 0.00019358521179424224 -4 100 1 15 3 5.0697970275832525 4.5525184191876846 10.342317645808219 2.7796117689908018 2.8204483845172778e-06 0.0094941563145769861 -3.2819606250814255 2.8204506613800378e-06 0.00015656123571357411 -4 100 1 15 5 5.2803700652454033 4.7465774385492079 8.9695169807914432 2.4493851795313168 2.3754165272475535e-06 0.0079960959206767362 -3.9027708106463241 2.3754184428479079e-06 0.0001318578097611939 -4 100 2 15 1 4.5911182715747261 4.2349453593757262 6.2446461252542598 1.5587418677029778 2.7792828976912555e-06 0.0046777927966987791 -3.6857396544290286 2.779285149670347e-06 0.00015427616706468759 -4 100 2 15 3 4.4589289917399908 4.320414881420076 4.3697787212913957 0.65142647773741447 1.1003937293970125e-06 0.0018520654609078464 -4.3328545493522128 1.1003954786648656e-06 6.1082180331105499e-05 -4 100 2 15 5 4.3192648651884973 4.3192647263053008 3.3614697354810676 7.117495334219015e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326390042217 3.1036885691353279e-12 1.7228357308550252e-10 -4 100 4 15 1 4.0051745686255105 4.0050287756412137 3.3621278877520977 0.00047547217990651092 1.5621620535007706e-09 1.3146323476484488e-06 -4.009758697609989 1.5626505833126274e-09 8.6741636597980988e-08 -4 100 4 15 3 4.1729334888883667 4.1729333291926638 3.3614693859629696 4.5960427863533937e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313162610707 4.0159515435019528e-12 2.2292265020826827e-10 -4 100 4 15 5 4.3192648651884973 4.3192647263053008 3.3614692421754837 3.5587478774967707e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960329948789674 3.1036885691353279e-12 1.7228357308550252e-10 -4 500 0.5 15 1 5.8702825782132528 4.4693976428357729 13.501402200605515 9.8335531406918584 5.5837864939537767e-06 0.037592137542268284 2.8889621435220949 5.5837871561608746e-06 0.00030995210414437271 -4 500 0.5 15 3 5.8702825782601371 4.7098874141239913 10.567452426355407 7.7803466063108395 3.9775195081876335e-06 0.026778147873445998 0.8357556091059184 3.9775201703947493e-06 0.00022078935167331389 -4 500 0.5 15 5 5.8702825785273234 4.8735460119823859 8.875148747928101 6.3580403652013358 3.0736699021056409e-06 0.020693094523689365 -0.58655063220394066 3.0736705643127693e-06 0.00017061729471622367 -4 500 1 15 1 5.8702825782132528 4.4693976428357729 8.3428186742278818 5.8739442971320459 5.5837864939537767e-06 0.018796068771134142 -1.0706467000377176 5.5837871561608746e-06 0.00030995210414437271 -4 500 1 15 3 5.8702825782601371 4.7098874141239913 6.8167957045207928 4.3859069671229562 3.9775195081876335e-06 0.013389073936722999 -2.5586840300819649 3.9775201703947493e-06 0.00022078935167331389 -4 500 1 15 5 5.8702825785273234 4.8735460119823859 5.9548480827837142 3.4772929254507421 3.0736699021056409e-06 0.010346547261844682 -3.4672980719545343 3.0736705643127693e-06 0.00017061729471622367 -4 500 2 15 1 4.8563641337472694 4.3103867659103585 4.781135635779564 2.1563139577946786 3.6850031690368115e-06 0.006202204638560499 -3.5668871649413814 3.6850056895078815e-06 0.00020455207824079277 -4 500 2 15 3 4.5564955803617426 4.3650348883150709 3.711881355241188 0.86352234233785541 1.4322220164880437e-06 0.0024105634721699417 -4.3140957427505944 1.432222529466955e-06 7.9501666914624203e-05 -4 500 2 15 5 4.3192648651884973 4.3192647263053008 3.036448972178853 7.1806364043691673e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326326901143 3.1036885691353279e-12 1.7228357308550252e-10 -4 500 4 15 1 4.0051745686255105 4.0050287756412137 3.0368155864825837 0.0004796939577117465 1.5621620535007706e-09 1.3146323476484488e-06 -4.0097544758321835 1.5626505833126274e-09 8.6741636597980988e-08 -4 500 4 15 3 4.1729334888883667 4.1729333291926638 3.0364487774738542 4.6368156880749467e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313121837811 4.0159515435019528e-12 2.2292265020826827e-10 -4 500 4 15 5 4.3192648651884973 4.3192647263053008 3.0364486973745968 3.590318917723323e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960329917218626 3.1036885691353279e-12 1.7228357308550252e-10 -4 900 0.5 15 1 5.8702825782132528 4.4693976428357729 13.185717640571141 9.9507027695248613 5.5837864939537767e-06 0.037592137542268284 3.0061117723550979 5.5837871561608746e-06 0.00030995210414437271 -4 900 0.5 15 3 5.8702825782601371 4.7098874141239913 10.434824816593402 7.815406050993067 3.9775195081876335e-06 0.026778147873445998 0.87081505378814583 3.9775201703947493e-06 0.00022078935167331389 -4 900 0.5 15 5 5.8702825785273234 4.8735460119823859 8.8018918053997481 6.3730049539106695 3.0736699021056409e-06 0.020693094523689365 -0.57158604349460695 3.0736705643127693e-06 0.00017061729471622367 -4 900 1 15 1 5.8702825782132528 4.4693976428357729 8.2830762785089043 5.8850294124181861 5.5837864939537767e-06 0.018796068771134142 -1.0595615847515774 5.5837871561608746e-06 0.00030995210414437271 -4 900 1 15 3 5.8702825782601371 4.7098874141239913 6.7855419764949385 4.3900378503937931 3.9775195081876335e-06 0.013389073936722999 -2.554553146811128 3.9775201703947493e-06 0.00022078935167331389 -4 900 1 15 5 5.8702825785273234 4.8735460119823859 5.9344272410723153 3.4793786629028034 3.0736699021056409e-06 0.010346547261844682 -3.465212334502473 3.0736705643127693e-06 0.00017061729471622367 -4 900 2 15 1 4.857856184044107 4.3107640975911483 4.7731740183004616 2.1594483969621301 3.6895256674024084e-06 0.006209816425865506 -3.5662679978213259 3.6895281917834511e-06 0.00020480311916644192 -4 900 2 15 3 4.5569937613003653 4.3652552236990925 3.7086286797008867 0.86458694622831989 1.4338592247349714e-06 0.0024133190466206524 -4.313999900177568 1.4338597897910465e-06 7.9592550085542404e-05 -4 900 2 15 5 4.3192648651884973 4.3192647263053008 3.0350365019205574 7.1809096136021822e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326326627939 3.1036885691353279e-12 1.7228357308550252e-10 -4 900 4 15 1 4.0051745686255105 4.0050287756412137 3.0354019141935389 0.00047971230368704099 1.5621620535007706e-09 1.3146323476484488e-06 -4.0097544574862081 1.5626505833126274e-09 8.6741636597980988e-08 -4 900 4 15 3 4.1729334888883667 4.1729333291926638 3.0350363078538862 4.6369916872901484e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313121661809 4.0159515435019528e-12 2.2292265020826827e-10 -4 900 4 15 5 4.3192648651884973 4.3192647263053008 3.0350362280172298 3.590454940027854e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960329917082611 3.1036885691353279e-12 1.7228357308550252e-10 -4 1500 0.5 15 1 5.8702825782132528 4.4693976428357729 13.122807197998259 9.9740486531383272 5.5837864939537767e-06 0.037592137542268284 3.0294576559685638 5.5837871561608746e-06 0.00030995210414437271 -4 1500 0.5 15 3 5.8702825782601371 4.7098874141239913 10.404249196708577 7.8234885630424138 3.9775195081876335e-06 0.026778147873445998 0.87889756583749268 3.9775201703947493e-06 0.00022078935167331389 -4 1500 0.5 15 5 5.8702825785273234 4.8735460119823859 8.7834535981536241 6.3767714254347707 3.0736699021056409e-06 0.020693094523689365 -0.5678195719705057 3.0736705643127693e-06 0.00017061729471622367 -4 1500 1 15 1 5.8702825782132528 4.4693976428357729 8.2676359682428373 5.8878943396996171 5.5837864939537767e-06 0.018796068771134142 -1.0566966574701464 5.5837871561608746e-06 0.00030995210414437271 -4 1500 1 15 3 5.8702825782601371 4.7098874141239913 6.7768662200959753 4.39118454677961 3.9775195081876335e-06 0.013389073936722999 -2.5534064504253111 3.9775201703947493e-06 0.00022078935167331389 -4 1500 1 15 5 5.8702825785273234 4.8735460119823859 5.9285442841392531 3.4799795344916244 3.0736699021056409e-06 0.010346547261844682 -3.464611462913652 3.0736705643127693e-06 0.00017061729471622367 -4 1500 2 15 1 4.8582940304503284 4.3108747300149357 4.7707467623666933 2.1603733238754277 3.690851638277215e-06 0.006212048158738743 -3.5660807923101503 3.6908541601978871e-06 0.00020487672274204202 -4 1500 2 15 3 4.5571482388002558 4.365323530523737 3.7076037754783036 0.8649174150202531 1.4343667775736364e-06 0.0024141733054708846 -4.3139697887237407 1.4343673590604204e-06 7.9620724899273962e-05 -4 1500 2 15 5 4.3192648651884973 4.3192647263053008 3.0345831060626614 7.1809975898950995e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960326326539956 3.1036885691353279e-12 1.7228357308550252e-10 -4 1500 4 15 1 4.0051745686255105 4.0050287756412137 3.0349481379325289 0.0004797181926101679 1.5621620535007706e-09 1.3146323476484488e-06 -4.0097544515972849 1.5626505833126274e-09 8.6741636597980988e-08 -4 1500 4 15 3 4.1729334888883667 4.1729333291926638 3.0345829121980019 4.6370484574342896e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818313121605037 4.0159515435019528e-12 2.2292265020826827e-10 -4 1500 4 15 5 4.3192648651884973 4.3192647263053008 3.0345828324444506 3.5904988737733845e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960329917038672 3.1036885691353279e-12 1.7228357308550252e-10 -6 100 0.5 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 0.5 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 0.5 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 1 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 1 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 1 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 2 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 2 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 2 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 4 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 4 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 100 4 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 0.5 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 0.5 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 0.5 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 1 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 1 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 1 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 2 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 2 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 2 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 4 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 4 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 500 4 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 0.5 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 0.5 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 0.5 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 1 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 1 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 1 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 2 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 2 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 2 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 4 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 4 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 900 4 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 0.5 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 0.5 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 0.5 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 1 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 1 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 1 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 2 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 2 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 2 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 4 15 1 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 4 15 3 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 -6 1500 4 15 5 5.8702829999999997 5.8702829999999997 2.5499403171431223 -0.64573991031390132 0 0 -7.5903312237695095 0 0 0.5 100 0.5 25 1 1.4064315157230882 1.1397291800324882 33.535719423557353 3.4216414573490117 7.9644452142332409e-06 0.053619621786311598 3.3030570555526011 7.9644455320981397e-06 0.00044210077891191453 0.5 100 0.5 25 3 1.5954124971659938 1.4018117298270372 31.191249087006778 3.2939585898339492 5.626586940336478e-06 0.037880286143406806 3.1008759409911337 5.6265870700498372e-06 0.00031232789731056547 0.5 100 0.5 25 5 1.7452545545113238 1.5881353349338942 29.262213724659755 3.1770775521522618 4.4519911133823881e-06 0.029972468046986948 2.9051006149550638 4.4519915504116376e-06 0.00024712692480775118 @@ -575,294 +287,6 @@ psi_soil ppfd vpd leaf_temp layers psi_stem opt_root_psi ci assim transpiration 6 1500 4 25 1 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 6 1500 4 25 3 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 6 1500 4 25 5 5.8702829999999997 5.8702829999999997 4.3305749999999996 -1.4399999999999999 0 0 -8.3845913134556085 0 0 -0.5 100 0.5 35 1 1.2271810577249567 1.0156742633135694 36.727526890478501 1.3937677093996341 6.4084874819047357e-06 0.043144332814037144 1.324198354893676 6.4084875654205928e-06 0.00035573064476384085 -0.5 100 0.5 35 3 1.3820725081190748 1.23590594075546 35.437272533569157 1.3188622296507599 4.3492676056184731e-06 0.029280895001193245 1.208076871496538 4.3492676238207038e-06 0.00024142479177467134 -0.5 100 0.5 35 5 1.5040185138680893 1.3907663555781669 34.321523320924868 1.2508842865693985 3.3145648367263044e-06 0.022314889254791897 1.0970581492150262 3.3145649539273518e-06 0.00018398917312946721 -0.5 100 1 35 1 1.3504861822474639 1.1011850264194769 34.839638048069958 1.2828345196212574 7.4810351834241664e-06 0.025182562395459452 1.181602117011151 7.4810354574219683e-06 0.00041526702511362579 -0.5 100 1 35 3 1.4975717374380502 1.3260225260646772 33.029360128404889 1.168155708412101 5.0431201297291511e-06 0.016976084755769449 1.0168633948284842 5.0431203539465276e-06 0.00027994006960569123 -0.5 100 1 35 5 1.6064561941983186 1.4749490741237072 31.546024349092519 1.0674427626544678 3.7997482905717835e-06 0.012790662798429315 0.86917986380342982 3.7997486375209519e-06 0.00021092137871334731 -0.5 100 2 35 1 1.4644152114378672 1.1794927780145676 32.124132557613137 1.1074588974675583 8.4631188194368302e-06 0.014244219717270863 0.96872933716878451 8.4631190387326913e-06 0.00046978179510034364 -0.5 100 2 35 3 1.5824429939934086 1.3917968196664439 29.801575499104395 0.94034020647078043 5.549490857078133e-06 0.0093403116243223078 0.75321804896464795 5.5494908623422954e-06 0.00030804834095710771 -0.5 100 2 35 5 1.6567817690446913 1.516112369582264 28.045578629532145 0.8018307996218148 4.0369688085848483e-06 0.0067945956955237762 0.57871443157383218 4.0369688249010042e-06 0.00022408930474054976 -0.5 100 4 35 1 1.5301446081095804 1.2243231693855137 28.651356039925037 0.85089148757819189 9.0252953516154122e-06 0.0075952076737017911 0.68648607969097408 9.0252955361138282e-06 0.00050098781771378454 -0.5 100 4 35 3 1.5808681646204101 1.3905800762562945 26.139769421686708 0.63790900482571766 5.5401240953393023e-06 0.004662273244570303 0.4515016191641506 5.5401241117661782e-06 0.00030752839920989057 -0.5 100 4 35 5 1.5929482323912298 1.4638777823902784 24.477209125600936 0.48176899447494614 3.7359431161039803e-06 0.0031439706645021341 0.28982905713192786 3.7359432001525863e-06 0.00020737958368873642 -0.5 500 0.5 35 1 2.1322280890259764 1.6191407399565589 31.20834819022889 8.1649378045074759 1.3974093007621385e-05 0.09407881675629505 7.5920860475746998 1.3974093041589783e-05 0.00077569209223368209 -0.5 500 0.5 35 3 2.3586780268021639 1.9676852789002786 28.704668773625173 7.4919803927468287 9.9801918441674942e-06 0.067190381457173654 6.6698264408576886 9.9801923954694454e-06 0.00055399347185508996 -0.5 500 0.5 35 5 2.5183118070645913 2.1911652834232003 26.845043734201283 6.928085273713755 7.9243754559577252e-06 0.053349857198068534 5.8957836746897136 7.9243766524831649e-06 0.00043987658354055872 -0.5 500 1 35 1 2.370533810076215 1.7650817464352881 26.820898540931893 6.9203662884235264 1.5802089032152963e-05 0.053192784591163556 6.0835871372969388 1.5802090039305326e-05 0.00087716292197087575 -0.5 500 1 35 3 2.5391188324462459 2.0923937723314689 23.828848171637418 5.8781288860595904 1.0938792233206911e-05 0.036822018770083571 4.8163389194220345 1.0938792548350884e-05 0.00060720469321958836 -0.5 500 1 35 5 2.6219165092091381 2.2671413953383865 21.779637204001766 5.0625388660084294 8.3614688112269048e-06 0.028146266511746596 3.8786717699609925 8.3614688613046955e-06 0.00046413926512931978 -0.5 500 2 35 1 2.4655402281598224 1.821221940614032 21.684482751016997 5.0226726306849869 1.6505052270116795e-05 0.027779545105834687 4.0629986468720229 1.6505052801645335e-05 0.00091618389129310767 -0.5 500 2 35 3 2.4737137235507287 2.0476906649233899 18.79350362530559 3.7331673878800138 1.0595214666547155e-05 0.017832736238481792 2.7624480368062878 1.0595214812072657e-05 0.00058813293433653381 -0.5 500 2 35 5 2.4359741829155896 2.129804930910387 17.045667668763731 2.8875767823301062 7.5712937418055553e-06 0.012743194784715637 1.9672326886665812 7.5712947059717175e-06 0.00042027725262124439 -0.5 500 4 35 1 2.2939339640625489 1.7189408099269561 17.070673038461024 2.8999839344063054 1.5224235734604677e-05 0.012811905602293443 2.154919206080177 1.5224236433618196e-05 0.00084508667408371896 -0.5 500 4 35 3 2.1662577056208447 1.8302689664896767 15.013750972256476 1.8522741306856525 8.9235037903717219e-06 0.0075095453195121549 1.2455666809284818 8.9235046570355199e-06 0.00049533747749295142 -0.5 500 4 35 5 2.0612830239485964 1.8411440826323697 13.929976412456043 1.2798497990403139 5.9094735850825503e-06 0.0049730980951136865 0.77357214099893956 5.9094736563857939e-06 0.00032803073307720201 -0.5 900 0.5 35 1 2.31303768515198 1.7305192008502881 30.9651442926423 9.2285313629617907 1.5369247337840501e-05 0.10347151712746407 8.4612081501937659 1.5369248316603311e-05 0.00085313618188194895 -0.5 900 0.5 35 3 2.5242954913245472 2.0823141638722542 28.497680197753063 8.3028476730406133 1.0861326278978993e-05 0.073122507784448121 7.2621150584721326 1.0861327325091763e-05 0.00060290465307198237 -0.5 900 0.5 35 5 2.661956830939185 2.2961143297518638 26.665911631845795 7.5574534895860754 8.5281215642451377e-06 0.05741450164103306 6.3118669372181193 8.528122736136889e-06 0.0004733901046981343 -0.5 900 1 35 1 2.5061495033005463 1.8448348450668783 26.550214707035927 7.5088085918416372 1.6800681790111687e-05 0.056554234419747218 6.4935209397990956 1.6800682856893055e-05 0.00093259410807066648 -0.5 900 1 35 3 2.6278485760090287 2.1520708779862319 23.600571505623687 6.2110131560317878 1.1397378196750006e-05 0.038365704818532291 5.018111707409358 1.1397378502768371e-05 0.00063266047753363151 -0.5 900 1 35 5 2.6807281065987572 2.3096192342338573 21.584973734062139 5.2661384147647201 8.605798065185739e-06 0.028968724437955437 3.991022923530732 8.605798225001681e-06 0.0004777018165418641 -0.5 900 2 35 1 2.5179411049525813 1.8516470006879908 21.453994693601466 5.2032539935237594 1.6885964274060162e-05 0.02842065559865373 4.1714734046716542 1.6885965475435848e-05 0.00093732808634115164 -0.5 900 2 35 3 2.4979443999609372 2.0643204240499156 18.630810656814695 3.8071890550247249 1.0723032337065257e-05 0.018047865320496823 2.8032865267470051 1.0723033034747442e-05 0.00059522803412419886 -0.5 900 2 35 5 2.4499316449211568 2.1402648257260828 16.921145145944244 2.9263225643677173 7.6314868422228315e-06 0.012844505396807987 1.987533739816683 7.6314879642873209e-06 0.00042361853812308191 -0.5 900 4 35 1 2.3066222912467951 1.7266361492868627 16.93815147517811 2.9352094974116789 1.5320615174131795e-05 0.012893013403220138 2.1754065883297229 1.5320616188729367e-05 0.0008504366466127875 -0.5 900 4 35 3 2.1720997625103111 1.8345021675013 14.923832765817018 1.8657223568802679 8.9560616294857524e-06 0.0075369442621333249 1.2530760040699729 8.9560625167381838e-06 0.00049714474142315761 -0.5 900 4 35 5 2.0648694667966918 1.8439711943208819 13.858942060751211 1.2868728690799189 5.9257551194311148e-06 0.0049867997668935158 0.77735837026339527 5.9257551301369353e-06 0.00032893450625239717 -0.5 1500 0.5 35 1 2.3661557920849847 1.7624652588214218 30.937684571541432 9.4975372904073438 1.5769323450393948e-05 0.1061649790402307 8.6661771916471988 1.5769324326685501e-05 0.00087534412027119081 -0.5 1500 0.5 35 3 2.5637458005334142 2.1090711579921742 28.465726959265041 8.483542743278937 1.1066957769062396e-05 0.074506895827688505 7.3862308056389114 1.1066958328000737e-05 0.00061431908565088742 -0.5 1500 0.5 35 5 2.6919732123077096 2.3176852868015683 26.631857954200381 7.6869817493142154 8.6521895764849537e-06 0.058249773868179498 6.3939964070138195 8.6521896667616304e-06 0.00048027697289823091 -0.5 1500 1 35 1 2.5336562255925146 1.8606944513471531 26.497584570708668 7.6272757881487294 1.6999228360412815e-05 0.057222579277433627 6.573274116116222 1.699922896667125e-05 0.00094361526320684149 -0.5 1500 1 35 3 2.6437448021733156 2.1626400624546891 23.55251223004224 6.2735988304708687 1.1478586089226946e-05 0.038639065759787511 5.0562997441809436 1.147858726950372e-05 0.00063716831915091427 -0.5 1500 1 35 5 2.6911583033955826 2.3171013698012195 21.54285303545079 5.304577165673301 8.6488312810601897e-06 0.029113582284131162 4.0128913368871277 8.6488313436142437e-06 0.00048009055473850922 -0.5 1500 2 35 1 2.5271309637052628 1.8569421198667895 21.405829174286549 5.2372467948208978 1.6952253679847026e-05 0.028532226862286098 4.1925051039950354 1.6952254612888007e-05 0.00094100774981337816 -0.5 1500 2 35 3 2.5025487176394452 2.0674713710193773 18.595034766038005 3.8221757612071356 1.0747249885561684e-05 0.018088625717361924 2.8118936765450364 1.0747250810459775e-05 0.00059657234584844718 -0.5 1500 2 35 5 2.4527867140560082 2.1424015619594936 16.892591831267747 2.9346638285288056 7.6437828876419026e-06 0.012865200790118611 1.9920751481784387 7.6437839519565224e-06 0.00042430107976444757 -0.5 1500 4 35 1 2.3092059348136673 1.7282005873639155 16.908013827891114 2.9428040046789152 1.5340208584356176e-05 0.01290950217327059 2.1799780105657098 1.5340209601359769e-05 0.00085152426318955152 -0.5 1500 4 35 3 2.1734109211700594 1.8354517435605917 14.902149712099357 1.8688583426506633 8.9633648486767835e-06 0.0075430902622675503 1.2548739757964207 8.9633657265315182e-06 0.00049755013747052556 -0.5 1500 4 35 5 2.065717304312797 1.8446393646778718 13.841264167049122 1.2885793408781767 5.9296031367500505e-06 0.0049900380532354799 0.77829766397249112 5.9296031403874277e-06 0.00032914810659935762 -1 100 0.5 35 1 1.5244849086572223 1.3686395881729871 35.614681637381977 1.329391172571714 4.5613446828893574e-06 0.030708677146331142 1.1673202265615941 4.5613447663767364e-06 0.00025319704503895291 -1 100 0.5 35 3 1.6900668219961628 1.5796807955307324 34.084826622622529 1.2360605194219443 3.1442240455745994e-06 0.021168091386182933 0.9953521295616895 3.1442245492655329e-06 0.00017453369687846421 -1 100 0.5 35 5 1.820652563933856 1.7339857985324918 32.798962899626147 1.1529284168568728 2.4090650297987754e-06 0.016218726136202778 0.83382386888325111 2.4090656100658491e-06 0.0001337255403866694 -1 100 1 35 1 1.6287652730833528 1.4400649465923978 33.417859734285784 1.1934994423628837 5.4566526794339695e-06 0.018368112594185321 0.98447395552651829 5.4566530696348407e-06 0.00030289498027392952 -1 100 1 35 3 1.7797977792253832 1.6489712320304548 31.367539915208681 1.0548837194009386 3.6774030732251403e-06 0.012378825934402204 0.76196054694275084 3.6774032452409448e-06 0.00020413007189791534 -1 100 1 35 5 1.8906710321428248 1.7909979673803336 29.725816319890615 0.93459230730218046 2.7374493996308595e-06 0.0092147662215731271 0.56695703998746549 2.7374500414726956e-06 0.00015195392958494008 -1 100 2 35 1 1.7143809740641234 1.498174670997346 30.408273642115645 0.98566882960810798 6.184939589920448e-06 0.010409831214296542 0.73151205385258922 6.1849396751704356e-06 0.00034332165834973275 -1 100 2 35 3 1.8229412536263563 1.6821010847418338 27.904878077878617 0.7902344319318475 3.9323024865736111e-06 0.006618432496171946 0.46961729431334293 3.9323030852078006e-06 0.00021827938302568974 -1 100 2 35 5 1.8867415832145316 1.7878064605386046 26.053058264913105 0.63008305602031633 2.7190677811975694e-06 0.0045764451294927778 0.26529641664105624 2.7190683724044218e-06 0.00015093357604243252 -1 100 4 35 1 1.7317569907587536 1.5099049678235619 26.785243027062798 0.6951281753684353 6.3319419778384123e-06 0.0053286249841014762 0.43104542566061277 6.3319420996747149e-06 0.00035148165970994808 -1 100 4 35 3 1.753929593785607 1.6290478172146314 24.263378432042828 0.46071138036400594 3.5241034964342812e-06 0.0029656977280246169 0.18357512767235507 3.5241040445426882e-06 0.00019562054091272208 -1 100 4 35 5 1.7428549660544808 1.6703040660867954 22.652950121909697 0.29430419460823209 2.0422177191970018e-06 0.0017186216171239822 0.023742505474394493 2.0422181066044033e-06 0.00011336209306713313 -1 500 0.5 35 1 2.4097969192207502 1.9459116622059209 29.98624382563888 7.8478573497518749 1.1792213023547683e-05 0.07938958525526342 6.9615173464211084 1.1792213034384958e-05 0.00065457746513377507 -1 500 0.5 35 3 2.6414168449318529 2.2783372444722936 27.432377171733513 7.1126279825068508 8.5156574619660684e-06 0.057330588646200061 5.8989189581550914 8.5156585430382221e-06 0.00047269822609149169 -1 500 0.5 35 5 2.8024000113263088 2.4942225081869083 25.569988105652921 6.5056648492280136 6.783693621895166e-06 0.04567036077669237 5.0301556604829827 6.783694789581669e-06 0.00037655813430927945 -1 500 1 35 1 2.6235245692667446 2.072093709686234 25.450492767022148 6.4644971744328945 1.3370809126381943e-05 0.045008642099284291 5.2781848314816813 1.3370809229016999e-05 0.00074220423141920617 -1 500 1 35 3 2.7735866529515736 2.3669460965843721 22.484517495204837 5.3524137528952327 9.1959964794881571e-06 0.030955442589850161 3.9257457130423679 9.1959973382292122e-06 0.00051046335488366429 -1 500 1 35 5 2.8386872041976505 2.5201606088834128 20.470399591606117 4.4991218219293305 6.9327512721219984e-06 0.023336936293153955 2.9609111350556634 6.9327519044198005e-06 0.00038483219008713851 -1 500 2 35 1 2.6499446326008562 2.0872338061930247 20.32229217124123 4.4334118973015606 1.3560159378805962e-05 0.022823015216248198 3.2065231820442248 1.3560160720650209e-05 0.00075271499975854616 -1 500 2 35 3 2.6228944199193758 2.2657128752630316 17.556494566720275 3.1393154198927973 8.4187087056416487e-06 0.014169473346333148 1.9539616291148019 8.4187087858417894e-06 0.00046731661314692143 -1 500 2 35 5 2.5625013403586903 2.3180488412826472 15.900923026519516 2.3106904690149004 5.7708871765441079e-06 0.0097129423159564212 1.2151896191227294 5.7708876636245707e-06 0.00032033792193308745 -1 500 4 35 1 2.3997238866863233 1.939809908739246 15.95821855136486 2.3399654766590161 1.1715855870858875e-05 0.0098594400457381673 1.4665054185636028 1.1715856222931422e-05 0.00065033895214717857 -1 500 4 35 3 2.2435662571701993 1.9973232543602839 14.095170372269429 1.3679471816731938 6.3565256514074356e-06 0.0053493132938869075 0.67961758459901711 6.3565265764579694e-06 0.00035284632675314844 -1 500 4 35 5 2.1221400823632703 1.9771030292523122 13.132055043767412 0.85020657992840487 3.8090899379790755e-06 0.0032055271323149226 0.28715026847247505 3.8090902778134552e-06 0.00021143992660635334 -1 900 0.5 35 1 2.5816264198949348 2.0478704314977563 29.844675383735439 8.819745491487593 1.3067829847900243e-05 0.087977514461406503 7.6962231410517328 1.306783112686707e-05 0.00072538612971785013 -1 900 0.5 35 3 2.7919324596471053 2.3790333029610231 27.318746195609606 7.8285212645810009 9.2887819722608287e-06 0.06253555179437377 6.3708531683848051 9.2887834689446125e-06 0.00051561384784594021 -1 900 0.5 35 5 2.9281359985694984 2.5832282700897977 25.468353005184088 7.0453976520962147 7.295110913500471e-06 0.049113413119101668 5.3471247401526476 7.2951125574111324e-06 0.00040494657548771206 -1 900 1 35 1 2.7387763789772008 2.1373534777502803 25.253882879952233 6.9517441284433605 1.4186893996166424e-05 0.047755736271341317 5.582945863780548 1.4186894807976517e-05 0.00078750456885798043 -1 900 1 35 3 2.8435526699444686 2.4127538283257004 22.311779670402871 5.6118691820041811 9.5476089579507497e-06 0.032139035897568516 4.065151665393941 9.5476099290985351e-06 0.00052998112290305493 -1 900 1 35 5 2.8832405471440694 2.5517315400877472 20.321037059698348 4.6521576967875333 7.1141569775434476e-06 0.023947581796571714 3.0351835290913538 7.1141574122744926e-06 0.00039490188244654413 -1 900 2 35 1 2.6882593233023426 2.1090014714804441 20.141895738728294 4.5638715328477186 1.3832377861137991e-05 0.023281184356510543 3.2768029059161661 1.3832377864056055e-05 0.00076782558224013629 -1 900 2 35 3 2.6401513904613836 2.2774763139715883 17.429582623260302 3.1909444752466452 8.5090460988360481e-06 0.01432151961967522 1.9791845146603217 8.5090471186824225e-06 0.00047233123056799459 -1 900 2 35 5 2.5723331683213262 2.3254186564632047 15.803732015448793 2.33704750145789 5.8132683800295343e-06 0.009784273841273344 1.2271916528697113 5.8132693975698267e-06 0.00032269050222424796 -1 900 4 35 1 2.4086481778524038 1.9452164824375444 15.853840266883502 2.3636962402552455 1.1783513680756646e-05 0.0099163772535415008 1.4788308348395365 1.1783513709649752e-05 0.00065409457172632538 -1 900 4 35 3 2.2477166258411874 2.0003515007062775 14.023225567698727 1.3767698209659738 6.3798038985267273e-06 0.0053689030263291944 0.68387177149653289 6.3798047417975116e-06 0.00035413848136539063 -1 900 4 35 5 2.1246933315957759 1.9791332088024252 13.074489350197986 0.8546424967949604 3.8207775282655945e-06 0.0032153627855509535 0.28911735924925752 3.8207777752222473e-06 0.00021208869138064098 -1 1500 0.5 35 1 2.628023265641608 2.0746791194378891 29.835430056245649 9.0542917137547381 1.3403144575394788e-05 0.090234978526261472 7.8611236388362684 1.3403144891008829e-05 0.00074399916131050951 -1 1500 0.5 35 3 2.8252563482863162 2.400851263807473 27.300116678166717 7.9813738736793418 9.4562545067914442e-06 0.06366303948743729 6.4665240443840677 9.4562545055849864e-06 0.00052491004749292177 -1 1500 0.5 35 5 2.9531248049979708 2.6006179440836386 25.445381922302005 7.1531657529713879 7.3950089356792394e-06 0.049785963939948989 5.4088249451309842 7.395009324304127e-06 0.00041049177487116997 -1 1500 1 35 1 2.7608331386637599 2.1496059341173188 25.212245859604629 7.0466509794771088 1.4340086265433988e-05 0.048271410076469276 5.641330166087231 1.4340086358112645e-05 0.00079600812423606139 -1 1500 1 35 3 2.8560635343690097 2.4208610575069676 22.273182652690224 5.6607671285285424 9.6098308500978372e-06 0.032348486413832547 4.0920684168079635 9.6098323926076077e-06 0.00053343504816028909 -1 1500 1 35 5 2.8913837255258907 2.5574683133145744 20.287196867983802 4.6817489323148607 7.1471181133798931e-06 0.024058535139187404 3.0501708693157856 7.147118146797463e-06 0.00039673150967512978 -1 1500 2 35 1 2.6952046125827658 2.1129230890782806 20.102627089697044 4.5891083806303818 1.3881416807362281e-05 0.023363721484917388 3.2909630645987829 1.3881417043469038e-05 0.00077054771265440121 -1 1500 2 35 3 2.6436139914030057 2.279831486680675 17.400582816045734 3.2018354978777928 8.527132188579359e-06 0.014351960198571304 1.9847382968885081 8.527133363783409e-06 0.00047333518533352258 -1 1500 2 35 5 2.5744585341775612 2.3270102226588532 15.780641312527376 2.3429607268177546 5.8224207954185568e-06 0.009799678211521055 1.229987730597617 5.822421900737436e-06 0.00032319855124826179 -1 1500 4 35 1 2.4105653005771597 1.9463765640987614 15.829242082673908 2.3690191711891857 1.1798030696323002e-05 0.0099285940003329635 1.4816919978300263 1.1798030699528234e-05 0.00065490039964075683 -1 1500 4 35 3 2.2486909706599496 2.001062150417146 14.005374180186825 1.3788956271576454 6.3852666650837887e-06 0.0053735001995913875 0.68492231448939389 6.3852674822714148e-06 0.00035444171425320095 -1 1500 4 35 5 2.1253210906372084 1.9796322801957107 13.059814582620028 0.85575130332575622 3.8236506340000658e-06 0.0032177806382495812 0.28961808722163962 3.8236508589322552e-06 0.00021224817423992536 -2 100 0.5 35 1 2.2924943391158052 2.1966220972656689 32.773627682353691 1.1512448854286839 2.3971135591961348e-06 0.016138264369404687 0.40784100389142552 2.3971141979848893e-06 0.00013306212589424865 -2 100 0.5 35 3 2.462810656557223 2.391526826396138 30.903621010666562 1.0217765986008822 1.690163169871706e-06 0.011378810135289404 0.065774611988355547 1.6901638396636238e-06 9.3819807919157577e-05 -2 100 0.5 35 5 2.5989638549189449 2.5417000698386252 29.4200937087064 0.91119474062220229 1.2958973791276225e-06 0.0087244654804729069 -0.23807725761641718 1.295898219585954e-06 7.1934400199053793e-05 -2 100 1 35 1 2.3444210877261438 2.2303492403754781 29.889291523871272 0.94697068364512482 2.8185527666708916e-06 0.0094877753106752359 0.14219519738245701 2.8185527756899989e-06 0.00015645588541160138 -2 100 1 35 3 2.4859628857014897 2.4086518059840119 27.501397693924382 0.75654766911691729 1.8215708678803905e-06 0.0061317479350702676 -0.23086459267115722 1.8215709691982471e-06 0.00010111412540650831 -2 100 1 35 5 2.5879978182106971 2.5331001401933158 25.65845425425314 0.59404044215455531 1.2464971045978631e-06 0.0041959421848257678 -0.53890642677135348 1.246498356510385e-06 6.9192248487948097e-05 -2 100 2 35 1 2.3454631106408939 2.2310229681164695 26.235556132166508 0.64651518181285983 2.8269705106326343e-06 0.0047580555049298286 -0.15952275646447567 2.8269705349437733e-06 0.00015692314931688999 -2 100 2 35 3 2.4102985451762065 2.3524706132313176 23.480870517907576 0.38162282017772009 1.3904276606595132e-06 0.0023402196662911769 -0.50536156684734934 1.3904276660887935e-06 7.7181663396546957e-05 -2 100 2 35 5 2.4331707823156132 2.4103780679242095 21.503261436843538 0.16636520945232425 5.413380728209483e-07 0.00091112255601046585 -0.75030053686520726 5.4133892603921728e-07 3.0049343660239649e-05 -2 100 4 35 1 2.2161264987064557 2.1464933523469587 22.335896857274868 0.25982233187030657 1.7705822229075985e-06 0.0014900276569830768 -0.39878312061389509 1.770582508060372e-06 9.8283791732465837e-05 -2 100 4 35 3 2.1713893130714541 2.1713888619558692 20.110909942180726 1.9001844648869337e-06 1.1500376674256073e-11 9.6781042352410862e-09 -0.61192023598081968 1.2390583932180694e-11 6.8779261349878953e-10 -2 100 4 35 5 2.316213588222487 2.3162132275844125 20.110906404535228 1.4604310845101054e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106166587657754 9.7500543226876377e-12 5.4121866903622745e-10 -2 500 0.5 35 1 3.1038197819873519 2.6817446021487621 27.369527542991769 7.0931728868023107 8.4501064005549744e-06 0.05688927440195455 5.0593680557872514 8.450106451146477e-06 0.00046905947550077582 -2 500 0.5 35 3 3.3378657532356817 2.9859871030047254 24.893365373433589 6.2688956061200702 6.2440236684670063e-06 0.042037100955839908 3.7513064834790986 6.2440256700531488e-06 0.0003466014804359228 -2 500 0.5 35 5 3.4989182215773296 3.1893462566169077 23.139392160831711 5.6129959255411794 5.0091349025383782e-06 0.033723368260569833 2.7442083517117659 5.0091359293190987e-06 0.00027805361805823475 -2 500 1 35 1 3.2336340671200556 2.7494080434837453 22.563465333830706 5.3842768046978691 9.2926252860579779e-06 0.031280713209621461 3.0866741800666229 9.2926254210331778e-06 0.00051582711190858608 -2 500 1 35 3 3.3321840267398475 2.9825540295468045 19.762218611050276 4.1814491425735518 6.2177770079470279e-06 0.020930199313941834 1.6760169709101782 6.2177787548119283e-06 0.00034514453260127274 -2 500 1 35 5 3.3580124865607615 3.0971791039661021 17.875888838947098 3.2948319712548213 4.4816574997325834e-06 0.015086096623654332 0.73399387756285206 4.4816587456306562e-06 0.00024877372998227345 -2 500 2 35 1 3.0762367953147161 2.6669650074127587 17.465709268064231 3.094843563976021 8.2660119327993956e-06 0.013912470410549247 1.1154483238275048 8.2660134262488264e-06 0.00045884060095747022 -2 500 2 35 3 2.9706566767178093 2.7514029222184364 15.004900958757629 1.8476538921213286 4.4490468478199612e-06 0.0074881615377102757 0.070651355612424194 4.4490471186508204e-06 0.00024696348146826646 -2 500 2 35 5 2.8575434478737622 2.7404216516422988 13.541005540475773 1.0712493160457268 2.4367918971583349e-06 0.0041013484424526105 -0.50005971542679784 2.4367934603551339e-06 0.00013526469388593584 -2 500 4 35 1 2.641226578697887 2.4168582224597079 13.644724062360506 1.1270305639357985 5.1475353940568627e-06 0.0043318915118489131 -0.086385300118391628 5.1475364662297113e-06 0.0002857361346783076 -2 500 4 35 3 2.4187103358830759 2.3587465426147762 12.186215642092591 0.3324050949043249 1.4385958521894316e-06 0.0012106456165945911 -0.5654270621553209 1.4385960081587888e-06 7.9855454241398212e-05 -2 500 4 35 5 2.316213588222487 2.3162132275844125 11.587401674861916 2.0863013019400967e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106104000636011 9.7500543226876377e-12 5.4121866903622745e-10 -2 900 0.5 35 1 3.2494835350655213 2.7574503829524248 27.403444959739758 7.8632579467958248 9.392732675024652e-06 0.063235386775554445 5.532638656595263 9.3927332423517482e-06 0.00052138402677500686 -2 900 0.5 35 3 3.4558690619563572 3.0557696581028857 24.906082930183693 6.7986506636377406 6.7773824711865854e-06 0.04562787175141466 4.0248659696361546 6.7773830612428528e-06 0.00037620777470124081 -2 900 0.5 35 5 3.5929454186812491 3.2485000412285352 23.131342130497821 5.9949914487967639 5.3474811987387379e-06 0.036001241978960312 2.9164892234464626 5.3474817489337508e-06 0.00029683495692110746 -2 900 1 35 1 3.3070921393900439 2.7862708639920024 22.462444512268426 5.6828442871416947 9.7514213455261271e-06 0.032825106480214174 3.2308824001488641 9.7514213450557595e-06 0.0005412945514879689 -2 900 1 35 3 3.3723052911775762 3.0066545332161478 19.663141718020743 4.3264297325806425 6.4020198476009347e-06 0.021550395141356388 1.7347787914457897 6.4020199489026625e-06 0.0003553716319124431 -2 900 1 35 5 3.3824834473631458 3.1134770426458331 17.788961689911051 3.37664029839156 4.574958532376353e-06 0.015400165334535209 0.7629830489607845 4.5749587498320934e-06 0.00025395274770092109 -2 900 2 35 1 3.094384784122898 2.6767046766005889 17.360207927740404 3.1549686503299763 8.3873319910971003e-06 0.014116663404098593 1.1398435596314709 8.3873321902818479e-06 0.00046557492035980281 -2 900 2 35 3 2.9785562564171668 2.7567030095412397 14.931708060128731 1.8699689637254857 4.4896333390886336e-06 0.0075564723946790228 0.078158936340156249 4.4896341866966468e-06 0.00024921644111555074 -2 900 2 35 5 2.8618327447302203 2.7436464556489675 13.485379747461092 1.0816532182658802 2.4552959921420833e-06 0.004132492563224309 -0.4972335092962521 2.4552975499834674e-06 0.00013629184290776949 -2 900 4 35 1 2.6450693435230734 2.4191964291717651 13.584154214834033 1.1360242189980205 5.1767153463048e-06 0.0043564478048673033 -0.083320124327020739 5.1767165743296882e-06 0.00028735590198888082 -2 900 4 35 3 2.4204419387995419 2.3600375550150345 12.143273492557801 0.33521128859796745 1.4485042386818324e-06 0.0012189839867186908 -0.56486378198499199 1.4485044676912994e-06 8.0405465872400743e-05 -2 900 4 35 5 2.316213588222487 2.3162132275844125 11.548723908445817 2.0891413621271226e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106103716629992 9.7500543226876377e-12 5.4121866903622745e-10 -2 1500 0.5 35 1 3.2830267381512455 2.7743103247548113 27.415037768659786 8.0315317421650825 9.6025746456148642e-06 0.064648121347177054 5.6305072348060428 9.6025763046750063e-06 0.00053303226781432173 -2 1500 0.5 35 3 3.4794683558397903 3.0693699227736611 24.902715021719267 6.9044296881820379 6.881295162361521e-06 0.046327450824372625 4.0786541665306606 6.8812973396600016e-06 0.00038197598332833759 -2 1500 0.5 35 5 3.6108353377794318 3.2595323048783413 23.122111252233935 6.069032296286327 5.4105642295896714e-06 0.03642594051908165 2.9503484254670997 5.4105663573502263e-06 0.0003003367392367597 -2 1500 1 35 1 3.3205185401551809 2.7928942775669725 22.435954261268765 5.7395319074603552 9.8338400275725335e-06 0.033102543165418372 3.2590033142841475 9.8338408055384549e-06 0.00054586959786502662 -2 1500 1 35 3 3.3798749262966958 3.0111642406955914 19.638585760368009 4.3549774539075159 6.4364914316195183e-06 0.02166643293480798 1.7469651051432344 6.4364915057648378e-06 0.00035728512382818972 -2 1500 1 35 5 3.3874145192932277 3.1167467105588722 17.767731547262322 3.3936947269920075 4.5936745118205184e-06 0.015463166818766848 0.76935723871015371 4.5936751262934719e-06 0.00025499168061579082 -2 1500 2 35 1 3.0980624722030483 2.6786711288667853 17.335377208504145 3.1676524506514903 8.4118253985519831e-06 0.01415788809736542 1.1452545418779758 8.4118254381291164e-06 0.00046693452334882691 -2 1500 2 35 3 2.9803445993925757 2.7579014341079509 14.913712573878039 1.8751363669657937 4.4988103170188584e-06 0.0075719181059785562 0.079966394976573874 4.4988113004219672e-06 0.0002497258562543418 -2 1500 2 35 5 2.862871493512269 2.7444270338495826 13.471246554287468 1.0842039848379716 2.4597749546849042e-06 0.0041400310756718513 -0.49652055165085529 2.4597764966716861e-06 0.00013654046609334921 -2 1500 4 35 1 2.6459933495754995 2.4197583457381491 13.568864139850621 1.1382215397018878 5.183727796243237e-06 0.0043623491090915836 -0.082550706307162436 5.1837290535255198e-06 0.00028774515978493035 -2 1500 4 35 3 2.4208888302971436 2.3603706881758812 12.132018103629591 0.33593864890879255 1.451060989794133e-06 0.001221135612223602 -0.56471581816424965 1.4510612390191051e-06 8.0547390453461284e-05 -2 1500 4 35 5 2.316213588222487 2.3162132275844125 11.538435135929339 2.0898968546845254e-06 8.8388811209760828e-12 7.4383313898929034e-09 -0.77106103641080737 9.7500543226876377e-12 5.4121866903622745e-10 -3 100 0.5 35 1 3.2026404976412541 3.1213111813649936 30.022892950528764 0.95701927221937311 1.443302220643957e-06 0.0097168499641343952 -1.276504057638892 1.4433041375011859e-06 8.0116799195181012e-05 -3 100 0.5 35 3 3.3703996161574552 3.3069339042635022 28.154458420852521 0.81075184495051467 1.0298506618893426e-06 0.0069333395486487013 -1.7767846721024427 1.0298508669972792e-06 5.7166298473343278e-05 -3 100 0.5 35 5 3.5072991590756168 3.4548888617253568 26.75370627600055 0.69237429584363763 7.8648018243740592e-07 0.0052948785245405128 -2.1949900824014601 7.8648046272517452e-07 4.3656978225099892e-05 -3 100 1 35 1 3.2059651727892433 3.1232075437376485 26.412262691971449 0.6622856668346575 1.4667950579212767e-06 0.0049375062624083628 -1.5780800477271213 1.4667969675380942e-06 8.1420869694037981e-05 -3 100 1 35 3 3.328343256921011 3.2789364127763529 23.997797861562312 0.43423068651350016 8.1660490282607972e-07 0.0027488447004527191 -2.0629937232892348 8.1660637664520701e-07 4.532924655260655e-05 -3 100 1 35 5 3.4146890933943501 3.3886377087302106 22.174590234032323 0.24204943007484303 4.0863519248584435e-07 0.0013755424188561659 -2.4415757234092839 4.0863725204648508e-07 2.2683166919038863e-05 -3 100 2 35 1 3.1017191740492418 3.0627709956460372 21.935665717620964 0.21543434272506357 7.1778469578041825e-07 0.0012080987085882678 -1.8142055286591998 7.1778469911213076e-07 3.9843724624597879e-05 -3 100 2 35 3 3.1718079687688916 3.1718075251234743 20.110915486303384 2.5893564141732384e-06 7.8357082936797437e-12 1.318822918086397e-08 -2.1704357981639291 7.8605668043621887e-12 4.3633454367816762e-10 -3 100 2 35 5 3.3170442487608387 3.3170439012574113 20.110909818095763 1.8847598637350416e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731246683636687 6.1738007589111003e-12 3.4270334492984183e-10 -3 100 4 35 1 3.0049013820550252 3.004900886809561 20.110907220723696 1.5618888666857345e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415925730379614 1.1003398397039095e-11 6.1079091851452102e-10 -3 100 4 35 3 3.1718079687688916 3.1718075251234743 20.11090507112322 1.294678884988798e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704370928414582 7.8605668043621887e-12 4.3633454367816762e-10 -3 100 4 35 5 3.3170442487608387 3.3170439012574113 20.11090223701833 9.4238029157978076e-07 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731256107432409 6.1738007589111003e-12 3.4270334492984183e-10 -3 500 0.5 35 1 4.0081079200039822 3.512878223112867 24.939602099050944 6.2853599130887066 6.2796426926771853e-06 0.042276901538953228 2.2685508954746876 6.2796434923385461e-06 0.00034857860074041336 -3 500 0.5 35 3 4.2554192041169667 3.8019069525693912 22.789429895289942 5.4747968746609157 4.7864550219612698e-06 0.032224204080919562 0.91448610389517437 4.786456409863963e-06 0.00026569283429719474 -3 500 0.5 35 5 4.4373459837746827 4.007177599031758 21.323490262467402 4.8698650858368016 3.9233986596716479e-06 0.026413786094298425 -0.070714909376484059 3.9234010880310727e-06 0.00021778523941332628 -3 500 1 35 1 4.005342063906502 3.5117839174579415 19.811342558105192 4.2037655650127075 6.2661714455661355e-06 0.021093104034352269 0.19315591004952015 6.2661719507505461e-06 0.00034783080492648049 -3 500 1 35 3 4.0563291841209193 3.7078010730638336 17.395625493237812 3.0604325893505666 4.0743801547396488e-06 0.013715124973197901 -1.0641201092374657 4.0743806824211367e-06 0.0002261660106811622 -3 500 1 35 5 4.0538384594088281 3.8070293711011152 15.773873176745258 2.2456288246241427 2.7894925876035822e-06 0.0093899533175094731 -1.8733754595846102 2.7894933727162627e-06 0.00015484281835782753 -3 500 2 35 1 3.6007903986991447 3.3326425866971379 14.729689145317172 1.7035237244212404 4.0573158869822435e-06 0.0068288417295781969 -1.3925893089133812 4.057317231336896e-06 0.00022521883049330535 -3 500 2 35 3 3.4133890379016747 3.3351900232707523 12.611851450036237 0.56653549629715583 1.2449894481437017e-06 0.0020954335657339582 -2.1142556753011492 1.2449915386577742e-06 6.9108606087026043e-05 -3 500 2 35 5 3.3170442487608387 3.3170439012574113 11.587402761205848 2.6924772527081586e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731238606462798 6.1738007589111003e-12 3.4270334492984183e-10 -3 500 4 35 1 3.0049013820550252 3.004900886809561 11.587401934608707 2.2312390646206381e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415919036877635 1.1003398397039095e-11 6.1079091851452102e-10 -3 500 4 35 3 3.1718079687688916 3.1718075251234743 11.587401250512038 1.8495156139941571e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704365380047292 7.8605668043621887e-12 4.3633454367816762e-10 -3 500 4 35 5 3.3170442487608387 3.3170439012574113 11.587400348576278 1.3462387382645602e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731252068847942 6.1738007589111003e-12 3.4270334492984183e-10 -3 900 0.5 35 1 4.1352539931201298 3.5612471952722555 25.01486135780285 6.8466929961893381 6.8748197751133297e-06 0.046283856097329067 2.5474244258797683 6.8748197768907267e-06 0.0003816164183675119 -3 900 0.5 35 3 4.3576166816863715 3.8460317541740077 22.814474386061256 5.8477292925026134 5.1199493957280896e-06 0.034469412844146799 1.0713012654433935 5.1199508148469167e-06 0.00028420487454048943 -3 900 0.5 35 5 4.5221982016091875 4.0456871062853477 21.323109820520294 5.1402408638018624 4.1411420974965e-06 0.027879716296411547 0.029776533549803474 4.1411443596699765e-06 0.00022987201552428403 -3 900 1 35 1 4.0500683199422403 3.5292597014345466 19.738236553500087 4.3638165485302505 6.4812752860908515e-06 0.021817183757639604 0.253214404376358 6.4812764898197194e-06 0.00035977110684539104 -3 900 1 35 3 4.08092179039995 3.7200026717187669 17.329429054784796 3.1389942563657356 4.1667676844558398e-06 0.014026118662519847 -1.040234465219084 4.1667689450392532e-06 0.00023129441826473789 -3 900 1 35 5 4.0694035092156984 3.8159602302253628 15.718462823444753 2.2916514902108349 2.8401653105775554e-06 0.0095605271721636159 -1.8619936561590369 2.8401654242919099e-06 0.00015765558835925116 -3 900 2 35 1 3.6087376662146498 3.3365197300563576 14.668555065719456 1.7277952570102451 4.1051925673075144e-06 0.0069094226558816842 -1.3861732393557822 4.1051945776187349e-06 0.00022787646836629116 -3 900 2 35 3 3.4165827247198108 3.3372742550103514 12.570938877140167 0.57461260201890729 1.2608558091990144e-06 0.0021221381338497186 -2.1131418651997973 1.2608578031801603e-06 6.9989331289489884e-05 -3 900 2 35 5 3.3170442487608387 3.3170439012574113 11.548724980631881 2.6961424923754862e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731238569810401 6.1738007589111003e-12 3.4270334492984183e-10 -3 900 4 35 1 3.0049013820550252 3.004900886809561 11.548724164807428 2.2342764212091026e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415919006504069 1.1003398397039095e-11 6.1079091851452102e-10 -3 900 4 35 3 3.1718079687688916 3.1718075251234743 11.548723489626312 1.8520333409099976e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704365354870023 7.8605668043621887e-12 4.3633454367816762e-10 -3 900 4 35 5 3.3170442487608387 3.3170439012574113 11.548722599445098 1.3480713616509377e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731252050521708 6.1738007589111003e-12 3.4270334492984183e-10 -3 1500 0.5 35 1 4.1614539446448511 3.5707439302946486 25.022370674081827 6.9595163466393331 6.9916102319199545e-06 0.04707013310141097 2.602774761446045 6.9916126073954083e-06 0.00038809950637776344 -3 1500 0.5 35 3 4.3773703484331756 3.8542315596011436 22.810433487968098 5.919870887336673 5.1818941606426518e-06 0.034886448152572934 1.1023876892997144 5.1818967654624032e-06 0.00028764345076116588 -3 1500 0.5 35 5 4.5384693764326167 4.0528282862443525 21.315088468325957 5.1925723577931482 4.1815061457121331e-06 0.028151462154518383 0.05013708489653812 4.1815067056849733e-06 0.00023211250100943511 -3 1500 1 35 1 4.058600069204422 3.5325399980931871 19.718296206088823 4.3953184176602864 6.5216446456861437e-06 0.021953074565789491 0.26570872131299339 6.5216449669416501e-06 0.0003620119326639828 -3 1500 1 35 3 4.0860206246134068 3.722512288839078 17.312515719060624 3.1556599051006766 4.185767236462917e-06 0.014090074704988959 -1.0348796208519757 4.1857690580459456e-06 0.0002323491011960003 -3 1500 1 35 5 4.0728492842306618 3.8179284309058636 15.704316723551671 2.3020013891502482 2.8513313419735888e-06 0.0095981141204195593 -1.859301909462157 2.8513317176588632e-06 0.00015827542146316199 -3 1500 2 35 1 3.6105667393157512 3.3374100818585246 14.653240435813904 1.7334698202175827 4.1161866460039655e-06 0.0069279267175500082 -1.3846102096797361 4.1161887603852674e-06 0.00022848674773162737 -3 1500 2 35 3 3.4173933471552638 3.3378029435277474 12.560267357216281 0.57667102452251617 1.264880433178602e-06 0.0021289119520446114 -2.1128516179864776 1.2648823919259202e-06 7.021273338473052e-05 -3 1500 2 35 5 3.3170442487608387 3.3170439012574113 11.538436204671257 2.6971174920120689e-06 5.7035115736958624e-12 9.5995428811818741e-09 -2.4731238560060405 6.1738007589111003e-12 3.4270334492984183e-10 -3 1500 4 35 1 3.0049013820550252 3.004900886809561 11.538435391467448 2.2350844006702175e-06 9.4529284748290355e-12 7.9550809246508393e-09 -1.8415918998424274 1.1003398397039095e-11 6.1079091851452102e-10 -3 1500 4 35 3 3.1718079687688916 3.1718075251234743 11.538434718455193 1.8527030896109409e-06 7.8357082936797437e-12 6.5941145904319848e-09 -2.1704365348172536 7.8605668043621887e-12 4.3633454367816762e-10 -3 1500 4 35 5 3.3170442487608387 3.3170439012574113 11.538433831133471 1.3485588605810506e-06 5.7035115736958624e-12 4.7997714405909371e-09 -2.4731252045646719 6.1738007589111003e-12 3.4270334492984183e-10 -4 100 0.5 35 1 4.1962194595268851 4.0898493094703312 28.151157577577848 0.810482062845018 1.0292211734426347e-06 0.0069291015971626379 -3.6220642357202215 1.0292215164921699e-06 5.7131363668729942e-05 -4 100 0.5 35 3 4.3690428176794081 4.2767255634586814 26.680921523169829 0.68600236413580351 7.7498386883723989e-07 0.0052174810447918772 -4.1142032423318673 7.7498632865195009e-07 4.3018946913791288e-05 -4 100 0.5 35 5 4.5148087930556438 4.4306594664553103 25.654409958405438 0.59366736095218409 6.226815319115559e-07 0.0041921247916617242 -4.5022116085645862 6.2268414025876682e-07 3.4564759381557971e-05 -4 100 1 35 1 4.1530533130750058 4.0715203665770359 23.959477722285961 0.43037953600340551 8.0742897857732545e-07 0.0027179568247423817 -3.9079653344208305 8.0743061850017962e-07 4.4819906661125706e-05 -4 100 1 35 3 4.2640128524057399 4.2225667026265805 21.993798695787667 0.22194228045536013 3.7092761481740551e-07 0.0012486116660746422 -4.3567670926580107 3.7092806033807039e-07 2.0589956166420782e-05 -4 100 1 35 5 4.345089833779789 4.3346701508967111 20.564891173839655 0.055701794133937277 8.624887340923556e-08 0.0002903298250726874 -4.6945649468398098 8.6248993086352754e-08 4.78762104281725e-06 -4 100 2 35 1 4.0051745686255105 4.0050287756412137 20.115047125800935 0.00051611850503219259 1.5621620535007706e-09 2.6292646952968977e-06 -4.0097180512848638 1.5626505833126274e-09 8.6741636597980988e-08 -4 100 2 35 3 4.1729334888883667 4.1729333291926638 20.110898670110686 4.989892286033637e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818312768761212 4.0159515435019528e-12 2.2292265020826827e-10 -4 100 2 35 5 4.3192648651884973 4.3192647263053008 20.110897764139928 3.8637084109893749e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960329643829137 3.1036885691353279e-12 1.7228357308550252e-10 -4 100 4 35 1 4.0051745686255105 4.0050287756412137 20.112970982688424 0.0002580861959002867 1.5621620535007706e-09 1.3146323476484488e-06 -4.0099760835939957 1.5626505833126274e-09 8.6741636597980988e-08 -4 100 4 35 3 4.1729334888883667 4.1729333291926638 20.110896663024612 2.4949463606205313e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818315263707142 4.0159515435019528e-12 2.2292265020826827e-10 -4 100 4 35 5 4.3192648651884973 4.3192647263053008 20.110896210039222 1.9318543476032346e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960331575683201 3.1036885691353279e-12 1.7228357308550252e-10 -4 500 0.5 35 1 5.2769648793079975 4.3979519355083525 22.702827326294504 5.4402234338285567 4.7324152396486999e-06 0.031860388069750778 -0.90757734476268048 4.7324173472116991e-06 0.00026269316387519839 -4 500 0.5 35 3 5.6140272091444308 4.6741061358639087 20.941739111739132 4.7056115617438898 3.7151301678076519e-06 0.025011644769527178 -2.0198528404579559 3.7151320940363796e-06 0.00020622437380163084 -4 500 0.5 35 5 5.8702825785273234 4.8735460119823859 19.690403138121891 4.1487503218249628 3.0736699021056409e-06 0.020693094523689365 -2.7958406755803136 3.0736705643127693e-06 0.00017061729471622367 -4 500 1 35 1 5.0061300640459656 4.345782647778142 17.436935307400855 3.0807240119077375 4.1089033786716284e-06 0.013831336596247851 -2.8844829187495438 4.1089053637676234e-06 0.00022808245149972929 -4 500 1 35 3 5.040148139926826 4.543766856116835 15.729122966355986 2.2226648588307207 2.7558764091132632e-06 0.0092767949789141595 -3.7945202635263056 2.7558770154496778e-06 0.00015297679797111728 -4 500 1 35 5 5.0507082932903096 4.6716273695999391 14.63425877381796 1.65334307106018 1.9614924732583415e-06 0.0066027502056798699 -4.3797495225697993 1.9614941981463217e-06 0.00010888116559235758 -4 500 2 35 1 4.2452271984643852 4.1100651526970795 12.634781716456743 0.57909743199277353 1.2736612673836964e-06 0.0021436909164414056 -3.9593424798266956 1.2736636138766865e-06 7.0700172849108328e-05 -4 500 2 35 3 4.1729334888883667 4.1729333291926638 11.587399213430825 7.128316927840217e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818310630336565 4.0159515435019528e-12 2.2292265020826827e-10 -4 500 2 35 5 4.3192648651884973 4.3192647263053008 11.587398925111476 5.5195053949574913e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960327988032153 3.1036885691353279e-12 1.7228357308550252e-10 -4 500 4 35 1 4.0051745686255105 4.0050287756412137 11.588058731101466 0.0003687192206469625 1.5621620535007706e-09 1.3146323476484488e-06 -4.009865450569249 1.5626505833126274e-09 8.6741636597980988e-08 -4 500 4 35 3 4.1729334888883667 4.1729333291926638 11.587398574688621 3.5641585238721518e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818314194494974 4.0159515435019528e-12 2.2292265020826827e-10 -4 500 4 35 5 4.3192648651884973 4.3192647263053008 11.587398430528946 2.7597527685330192e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330747784784 3.1036885691353279e-12 1.7228357308550252e-10 -4 900 0.5 35 1 5.4218059803108645 4.4202651495827521 22.641181992248924 5.7667290659645438 4.9986257952601106e-06 0.033652617022735289 -0.75645196058430209 4.9986273443096752e-06 0.00027747029388341244 -4 900 0.5 35 3 5.735186641536008 4.6924572330862695 20.834604646663415 4.903538396596554 3.8497544181484048e-06 0.025917985536820891 -1.9324093685767556 3.8497553607025467e-06 0.00021369721680280579 -4 900 0.5 35 5 5.8702825785273234 4.8735460119823859 19.41853769307605 4.2042857349746026 3.0736699021056409e-06 0.020693094523689365 -2.7403052624306738 3.0736705643127693e-06 0.00017061729471622367 -4 900 1 35 1 5.0378732031454758 4.3526598668881196 17.357373717309365 3.1534980222122173 4.1911865174630245e-06 0.014108317017526951 -2.8602460472135971 4.191186904279446e-06 0.00023264984203605032 -4 900 1 35 3 5.0601941514148194 4.5497103597692314 15.66634533658064 2.263875290809755 2.7997314955286867e-06 0.0094244193949123197 -3.7834141791659346 2.7997338417599523e-06 0.00015541125960366096 -4 900 1 35 5 5.0654865555556317 4.6769409959785291 14.583085743431475 1.6814977442839694 1.9908781908017643e-06 0.0067016680221890397 -4.373674523037419 1.9908805902758392e-06 0.00011051238358455949 -4 900 2 35 1 4.2489833553929461 4.1115885119073132 12.595490491026544 0.58831250710880489 1.2920736431858946e-06 0.0021746806652608512 -3.9581939652174629 1.2920756982424543e-06 7.1722214723422394e-05 -4 900 2 35 3 4.1729334888883667 4.1729333291926638 11.54872147909351 7.1380206234650245e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818310620632879 4.0159515435019528e-12 2.2292265020826827e-10 -4 900 2 35 5 4.3192648651884973 4.3192647263053008 11.548721194531698 5.5270189980305418e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960327980518546 3.1036885691353279e-12 1.7228357308550252e-10 -4 900 4 35 1 4.0051745686255105 4.0050287756412137 11.549372401013832 0.00036922127692529116 1.5621620535007706e-09 1.3146323476484488e-06 -4.0098649485129698 1.5626505833126274e-09 8.6741636597980988e-08 -4 900 4 35 3 4.1729334888883667 4.1729333291926638 11.548720848675762 3.5690103938890161e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818314189643104 4.0159515435019528e-12 2.2292265020826827e-10 -4 900 4 35 5 4.3192648651884973 4.3192647263053008 11.548720706394853 2.7635095634082063e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330744027985 3.1036885691353279e-12 1.7228357308550252e-10 -4 1500 0.5 35 1 5.449623371780568 4.4241486202264442 22.618696178833254 5.8276876169250897 5.0449299619962966e-06 0.033964353978761748 -0.72688580479238052 5.0449301748517087e-06 0.00028004053149329497 -4 1500 0.5 35 3 5.7582356203441663 4.6956476807831411 20.806046965742397 4.9406857166716893 3.8731474356408131e-06 0.026075476073404897 -1.9148574847056761 3.8731491389301129e-06 0.00021499578900527967 -4 1500 0.5 35 5 5.8702825785273234 4.8735460119823859 19.363725726377293 4.2154824695049751 3.0736699021056409e-06 0.020693094523689365 -2.7291085279003013 3.0736705643127693e-06 0.00017061729471622367 -4 1500 1 35 1 5.0444218533177878 4.3540523607220267 17.337565595966531 3.1688002108981093 4.2078429496343866e-06 0.01416438568077431 -2.8548357286003987 4.2078440163460504e-06 0.00023357446663036641 -4 1500 1 35 3 5.0646404435354739 4.5510136796894862 15.650556237345734 2.2731245256174186 2.8093471428066532e-06 0.0094567874605092639 -3.7807893249556597 2.8093495490660504e-06 0.00015594502076414379 -4 1500 1 35 5 5.068923263964721 4.6781667587694438 14.5700034203666 1.6880910045819122 1.9976563392674605e-06 0.0067244845365454055 -4.3721854984051962 1.9976586525488048e-06 0.00011088862906182651 -4 1500 2 35 1 4.2499368418836836 4.1119746203703178 12.585225411206736 0.59065849378589519 1.296740257548478e-06 0.0021825350132541402 -3.9578944816190278 1.2967422248795227e-06 7.1981250340245496e-05 -4 1500 2 35 3 4.1729334888883667 4.1729333291926638 11.538432714380747 7.1406019186426306e-07 1.510000983184767e-12 2.5414727403307479e-09 -4.3818310618051584 4.0159515435019528e-12 2.2292265020826827e-10 -4 1500 2 35 5 4.3192648651884973 4.3192647263053008 11.538432430733025 5.5290177325417744e-07 1.1692042524380496e-12 1.9678800004373867e-09 -4.6960327978519816 3.1036885691353279e-12 1.7228357308550252e-10 -4 1500 4 35 1 4.0051745686255105 4.0050287756412137 11.539081545269841 0.0003693548276828551 1.5621620535007706e-09 1.3146323476484488e-06 -4.0098648149622127 1.5626505833126274e-09 8.6741636597980988e-08 -4 1500 4 35 3 4.1729334888883667 4.1729333291926638 11.538432085988063 3.5703010325960349e-07 1.510000983184767e-12 1.2707363701653739e-09 -4.3818314188352465 4.0159515435019528e-12 2.2292265020826827e-10 -4 1500 4 35 5 4.3192648651884973 4.3192647263053008 11.5384319441642 2.7645089106798082e-07 1.1692042524380496e-12 9.8394000021869334e-10 -4.6960330743028642 3.1036885691353279e-12 1.7228357308550252e-10 -6 100 0.5 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 0.5 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 0.5 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 1 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 1 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 1 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 2 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 2 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 2 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 4 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 4 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 100 4 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 0.5 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 0.5 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 0.5 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 1 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 1 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 1 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 2 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 2 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 2 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 4 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 4 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 500 4 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 0.5 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 0.5 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 0.5 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 1 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 1 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 1 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 2 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 2 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 2 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 4 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 4 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 900 4 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 0.5 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 0.5 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 0.5 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 1 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 1 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 1 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 2 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 2 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 2 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 4 35 1 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 4 35 3 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 -6 1500 4 35 5 5.8702829999999997 5.8702829999999997 7.1061162702981164 -2.5920000000000001 0 0 -9.5365913134556077 0 0 0.5 100 0.5 40 1 0.82641094739989962 0.73372936184098259 39.441595349036596 0.10655990305622698 2.8713492365914783e-06 0.019330996188825163 0.092050258703126164 2.871349236317001e-06 0.00015938657986772141 0.5 100 0.5 40 3 0.94808278259378109 0.89262157993669611 39.179286955229152 0.093023799404440499 1.7054695331580889e-06 0.011481858293480387 0.06795100225067785 1.7054695970183945e-06 9.4669419762331093e-05 0.5 100 0.5 40 5 1.0484247140995155 1.0114754122577319 38.931281577659718 0.080111405158991289 1.1279043766681671e-06 0.0075934738027945642 0.042736439156290024 1.1279044608277508e-06 6.2609184614363073e-05 diff --git a/tests/cpp/test_golden.cpp b/tests/cpp/test_golden.cpp index c3d8fed..6f58a0d 100644 --- a/tests/cpp/test_golden.cpp +++ b/tests/cpp/test_golden.cpp @@ -59,18 +59,15 @@ struct Row { const double kTheta = 0.000157, kKs = 1.0, kH = 5.0; const double kAreaLeaf = 0.05; const double kCa = 40.0, kO2 = 21.0, kPatm = 101.3; -// ⚠️ LEAF TEMPERATURE IS A GRID AXIS, NOT A FIXED DRIVER, and it was fixed at 25 C -// until #41. That single value made this whole file blind to every temperature -// response in the model: the reference values of Vcmax, Jmax and R_d are DEFINED at -// 25 C, so a change to any response curve is inert there BY CONSTRUCTION and a -// bit-identical run said nothing about it. #41 changed R_d's shape at every -// temperature except 25 C and this file did not move a bit. +// ⚠️ LEAF TEMPERATURE IS A GRID AXIS, NOT A FIXED DRIVER. It was fixed at 25 C, and +// that made this file blind to every temperature response in the model: the +// reference values of Vcmax, Jmax and R_d are DEFINED at 25 C, so a change to any +// response curve is inert there BY CONSTRUCTION. // -// 40 C is in the list deliberately -- it is where the response bites hardest -- and -// the extra shut-down rows at the hot end are a feature rather than noise: they pin -// the temperature at which the model stops having an operating point, which is a -// limit a caller needs and which moved in #41. -const double kLeafTemps[] = {15.0, 25.0, 35.0, 40.0}; +// Two temperatures are enough to see one: the reference, and 40 C where the response +// bites hardest. The extra pinned rows at the hot end are a feature rather than +// noise. +const double kLeafTemps[] = {25.0, 40.0}; Row solve(double psi_soil, double ppfd, double vpd, int layers, double leaf_temp) { @@ -111,11 +108,11 @@ std::vector run_grid() { const double vpds[] = {0.5, 1.0, 2.0, 4.0}; const int layer_counts[] = {1, 3, 5}; - // ⚠️ TEMPERATURE IS THE OUTERMOST LOOP ON PURPOSE. It makes the file four - // contiguous copies of the original 288-point grid, so the 25 C block is - // byte-identical to the pre-#41 file's rows in all nine output columns -- which - // is what makes a regeneration checkable as an ADDITION rather than taken on - // trust. Reordering these loops rewrites every row without changing any value. + // ⚠️ TEMPERATURE IS THE OUTERMOST LOOP ON PURPOSE. It makes the file contiguous + // copies of one 288-point state grid, so a regeneration that only adds a + // temperature is checkable as an ADDITION: the 25 C block must come out + // byte-identical. Reordering these loops rewrites every row without changing any + // value. std::vector rows; for (double t : kLeafTemps) { for (double p : psi_soils) { @@ -139,10 +136,9 @@ std::vector run_grid() { // the point, and the grid's split between those branches is already an // established number AT 25 C: 240 of those 288 points are feasible, of which 198 sit // at an interior profit maximum and 42 at a constrained optimum pinned to a bracket -// bound (24 wet, 18 dry); the remaining 48 shut down. Those figures were measured -// when PLAN 11a replaced the collar solver and are quoted in the developer guide -// and in maximise_profit_over_collar's own comment. The other three temperatures -// have no such history, so their counts were measured when the axis was added. +// bound (24 wet, 18 dry); the remaining 48 shut down. Those figures are quoted in +// the developer guide and in maximise_profit_over_collar's own comment. The 40 C +// counts were measured when the axis was added. // // So this asserts the classification against numbers that already exist rather // than inventing reference values for it. It is a cheap test with a specific @@ -158,17 +154,13 @@ std::vector run_grid() { // // ⚠️ The hot end does NOT reach the compensation-point exit either, which is worth // knowing before reading the zeros as coverage: at the defaults that needs about -// 45 C, and 40 C is the top of this grid. `test_rd_temperature_response` in -// test_leaf.cpp is what covers it. +// 45 C. `test_rd_temperature_response` covers it. // // A zero counts for this grid, whose psi_soil values are {0.5, 1, 2, 3, 4, 6}, // and says nothing about the model. What the two failure branches do is checked // by test_collar_solve_refuses_rather_than_guessing in test_leaf.cpp. -// ⚠️ COUNTED PER TEMPERATURE, NOT OVER THE WHOLE GRID, and that is most of the -// value of the split once temperature is an axis: a single total would let points -// move between branches as the leaf warms and still add up. Only the 25 C row -// reproduces the historic 198/24/18/48, and it must, because that block is -// byte-identical to the pre-#41 file. +// ⚠️ COUNTED PER TEMPERATURE, not over the whole grid: a single total would let +// points move between branches as the leaf warms and still add up. struct KindCount { phylloptim::Leaf::OperatingPointKind kind; int expected; @@ -180,20 +172,13 @@ struct TempKinds { int interior, pinned_wet, pinned_dry, shutdown; }; // -// ⚠️ AND THE SPLIT MOVES WITH TEMPERATURE IN A SPECIFIC DIRECTION, which is the -// measurement this table records rather than a bookkeeping detail. As the leaf -// warms, DRY-pinned points disappear and WET-pinned ones proliferate: 18 -> 18 -> 3 -// -> 0 dry against 24 -> 24 -> 43 -> 80 wet. A hot leaf assimilates less and -// respires more, so it has less to gain from water and its optimum presses against -// the WET bound instead of the dry one. -// -// The 48 shut-down rows are temperature-INDEPENDENT, and that is the right answer: -// they are the psi_soil = 6 MPa rows, where hydraulics forbid transpiration whatever -// the leaf temperature. +// The split MOVES with temperature, in a direction that is physical: a hot leaf +// assimilates less and respires more, so it has less to gain from water and its +// optimum presses against the WET bound instead of the dry one. The 48 shut-down +// rows do not move, because there it is hydraulics rather than heat that forbids +// transpiration. const TempKinds kExpectedKinds[] = { - {15.0, 198, 24, 18, 48}, {25.0, 198, 24, 18, 48}, - {35.0, 194, 43, 3, 48}, {40.0, 160, 80, 0, 48}, }; diff --git a/tests/cpp/test_leaf.cpp b/tests/cpp/test_leaf.cpp index 4cb041c..a29766d 100644 --- a/tests/cpp/test_leaf.cpp +++ b/tests/cpp/test_leaf.cpp @@ -61,11 +61,9 @@ struct Drivers { double area_leaf = 0.05; }; -// set_traits' fourteenth argument, R_d_25. NaN is the SENTINEL for "derive as -// rd_to_vcmax_ratio_ * vcmax_25", so passing it keeps a call at the default -// respiration rather than pinning one -- which is what every call below wants -// except the tests that are specifically about R_d. -const double kRdDefault = std::numeric_limits::quiet_NaN(); +// set_traits' fourteenth argument, R_d_25: dark respiration at 25 C. The class +// default, so a call that is not about respiration can pass it and change nothing. +const double kRd25 = 1.44; phylloptim::Leaf make_leaf(const Drivers &d, std::vector psi_soil, std::vector soil_depth) { @@ -2009,7 +2007,7 @@ void test_temperature_parameters_are_settable() { ok(base.vcmax_ha_ == phylloptim::vcmax_ha, "vcmax_ha_ defaults to the constant"); ok(base.jmax_d_S_ == phylloptim::jmax_d_S, "jmax_d_S_ defaults to the constant"); ok(base.gamma_25_ == phylloptim::gamma_25, "gamma_25_ defaults to the constant"); - near(base.rd_to_vcmax_ratio_, 0.015, 1e-12, "rd_to_vcmax_ratio_ default"); + near(base.R_d_25, 1.44, 1e-12, "R_d_25 default"); // Raising the Vcmax activation energy raises Vcmax above the 25 C reference, // so a 25 C leaf should be unaffected but a warm one should assimilate more. @@ -2024,14 +2022,13 @@ void test_temperature_parameters_are_settable() { "a larger activation energy gives a larger vcmax at 35 C"); } - // Respiration fraction: doubling it must lower assimilation. + // Respiration: doubling it must lower assimilation. { phylloptim::Leaf r2 = make_leaf(d, {2.0}, {1.0}); - r2.rd_to_vcmax_ratio_ = 0.030; + r2.R_d_25 = 2.0 * r2.R_d_25; r2.update_temperature_dependent_params(d.leaf_temp); r2.find_root_collar_psi(); - ok(r2.assim_colimited_ < A_base, - "doubling the respiration fraction lowers assimilation"); + ok(r2.assim_colimited_ < A_base, "doubling R_d_25 lowers assimilation"); ok(r2.R_d_ > base.R_d_, "and raises R_d"); } @@ -2069,7 +2066,7 @@ void test_temperature_params_invalidate_cache() { const double A_before = warm.assim_colimited_; const double Rd_before = warm.R_d_; - warm.rd_to_vcmax_ratio_ = 0.030; + warm.R_d_25 = 2.0 * warm.R_d_25; warm.set_physiology(fixture::root_network({1.0 / d.area_leaf}, {1.0}), d.PPFD, {2.0}, {1.0}, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); @@ -2080,11 +2077,11 @@ void test_temperature_params_invalidate_cache() { ok(warm.assim_colimited_ != A_before, "and the operating point moves"); near(warm.R_d_, 2.0 * Rd_before, 1e-12, - "doubling the ratio doubles R_d at the same temperature"); + "doubling R_d_25 doubles R_d at the same temperature"); // And it must agree bit-for-bit with never having had the stale value. phylloptim::Leaf fresh = make_leaf(d, {2.0}, {1.0}); - fresh.rd_to_vcmax_ratio_ = 0.030; + fresh.R_d_25 = 2.0 * fresh.R_d_25; fresh.set_physiology(fixture::root_network({1.0 / d.area_leaf}, {1.0}), d.PPFD, {2.0}, {1.0}, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); @@ -2119,31 +2116,25 @@ void test_temperature_params_invalidate_cache() { "unchanged inputs still give a bit-identical answer"); } -// R_d's TEMPERATURE RESPONSE, and the blast radius of changing it (#41). +// R_d's TEMPERATURE RESPONSE (#41). // -// ⚠️ THE GOLDEN FILE CANNOT SEE ANY OF THIS. Its grid is 6 psi_soil x 4 PPFD x 4 -// VPD x 3 layer counts, all at ONE leaf temperature (25 C), so a change to how R_d -// varies with temperature leaves it bit-identical BY CONSTRUCTION. Reading that -// silence as "no results moved" would be exactly the mistake the guide warns about. -// This is the test that can see it. -// -// The old response is exactly reproducible, which is what makes this a measurement -// rather than archaeology: R_d used to be `ratio * vcmax_(T)`, so setting -// `R_d_25 = ratio * vcmax_(T)` with `rd_q10_ = 1` reconstructs it at any T. +// ⚠️ THE GOLDEN FILE IS NEARLY BLIND TO THIS, and that is the reason this test +// exists. Every reference value in the model is DEFINED at 25 C, so a change to any +// response curve is inert there by construction; the golden grid carries one hot +// block for exactly this reason, and this test is what pins the response itself. void test_rd_temperature_response() { - printf("R_d rises with temperature, and the change is measured\n"); + printf("R_d rises with temperature\n"); Drivers d; - // At the reference the two forms must agree EXACTLY, not approximately -- the - // default reference value is `ratio * vcmax_25` and vcmax_(25) == vcmax_25. + // R_d IS R_d_25 at the reference, exactly. The trait is the value there, not a + // scale on anything. { phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); - near(l.R_d_, 0.015 * l.vcmax_25, 1e-12, "R_d at 25 C is ratio * vcmax_25"); - near(l.R_d_, 0.015 * l.vcmax_, 1e-12, "and equals the old form there"); + near(l.R_d_, l.R_d_25, 1e-12, "R_d at 25 C is R_d_25"); } - // The direction that was wrong: R_d must now RISE above the thermal optimum. - // vcmax_ peaks near 31 C, so 45 C is comfortably past it -- the old form fell. + // The direction: R_d must RISE, including above Vcmax's thermal optimum near + // 31 C, so 45 C is comfortably past it. double rd_prev = -1.0; for (double T : {25.0, 35.0, 45.0}) { phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); @@ -2167,9 +2158,7 @@ void test_rd_temperature_response() { ok(q10_at_30 < 2.0, "and that Q10 is below 2, i.e. the decline is active"); } - // ⚠️ A CONSTANT Q10 MUST STILL BE REACHABLE -- slope zero, intercept the value. - // Kept as an assertion because it is the escape hatch for anyone who wants the - // conventional form, and a silent loss of it would be hard to notice. + // A constant Q10 must stay reachable: slope zero, intercept the value. { phylloptim::Leaf a = make_leaf(d, {2.0}, {1.0}); phylloptim::Leaf b = make_leaf(d, {2.0}, {1.0}); @@ -2181,150 +2170,45 @@ void test_rd_temperature_response() { "slope zero recovers a constant Q10 exactly"); } - // Setting the value directly overrides the ratio entirely. + // A measured value is used verbatim, and is INDEPENDENT of vcmax_25 -- R_d_25 is + // a trait in its own right, not a fraction of Vcmax. { phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); l.R_d_25 = 0.525; // Sabot's Rlref, as measured l.update_temperature_dependent_params(25.0); near(l.R_d_, 0.525, 1e-12, "a set R_d_25 is used verbatim at 25 C"); - ok(l.R_d_ != 0.015 * l.vcmax_25, "and the ratio no longer applies"); + l.vcmax_25 = 2.0 * l.vcmax_25; + l.update_temperature_dependent_params(25.0); + near(l.R_d_, 0.525, 1e-12, "and does not follow vcmax_25"); } - // ⚠️ The sentinel must keep respiration TIED to Vcmax for a caller who changes - // vcmax_25 and never touches R_d_25 -- which is what plant does per individual. - // A default computed at construction would silently decouple them. - { + // An unset or negative R_d_25 FAILS rather than falling back to a derivation. + for (double bad : {std::numeric_limits::quiet_NaN(), -1.0}) { phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); - const double rd_default = l.R_d_; - l.vcmax_25 = l.vcmax_25 * 2.0; - l.update_temperature_dependent_params(d.leaf_temp); - near(l.R_d_, 2.0 * rd_default, 1e-12, - "R_d still scales with vcmax_25 while R_d_25 is unset"); - } - - // THE BLAST RADIUS. The old form is the `rd_tracks_vcmax_` branch itself, so the - // "old" column below is the escape hatch rather than an emulation of it -- which - // makes this table evidence that the hatch reproduces what plant used to compute, - // not merely a record of what changed. The emulation it used to use survives just - // above, as the bit-exactness check on the branch. - // - // ⚠️⚠️ AND A LIMIT THIS CHANGE MAKES REACHABLE, which is the most important thing - // here. A higher R_d can drive net assimilation negative across the WHOLE - // [gamma*, ca] bracket, and then psi_stem_to_ci has no supply==demand root and - // THROWS: "toms748_solve: Parameters a and b do not bracket the root". At the - // defaults that happens by 45 C. - // - // The model already knows this physical case -- `ci_at_compensation_point_` - // places ci at the compensation point instead -- but that fallback fires only on - // the ENERGY-BALANCE path. On the default prescribed-temperature path the same - // situation is an exception. Raising R_d is what makes it reachable there. - // - // Recorded as a measured limit rather than avoided by choosing a cooler sweep: - // the temperature at which the model stops having an operating point is exactly - // what a caller needs to know, and it moved. - // ⚠️ THE ESCAPE HATCH BACK TO THE OLD SHAPE, and it is checked against the same - // emulation the blast-radius table below uses rather than against a recorded - // number. That is the strong form: the table's "then" arm and `rd_tracks_vcmax_` - // are two independent routes to `rd_to_vcmax_ratio_ * vcmax_(T)`, so if either - // drifts they stop agreeing. BIT-EXACT, deliberately -- reproducing an old plant - // result is the whole reason the flag exists, and "close" does not reproduce it. - { - for (double T : {15.0, 25.0, 35.0, 40.0, 45.0}) { - phylloptim::Leaf old_shape = make_leaf(d, {2.0}, {1.0}); - old_shape.rd_tracks_vcmax_ = true; - old_shape.update_temperature_dependent_params(T); - - phylloptim::Leaf emulated = make_leaf(d, {2.0}, {1.0}); - emulated.update_temperature_dependent_params(T); // seat vcmax_(T) - ok(old_shape.R_d_ == 0.015 * emulated.vcmax_, - "rd_tracks_vcmax_ reproduces ratio * vcmax_(T) bit-exactly"); - // And it really is PEAKED, which is the property no Q10 can imitate: R_d - // above the thermal optimum is BELOW its 25 C value under the old shape and - // above it under the new one. - if (T == 45.0) { - phylloptim::Leaf at25 = make_leaf(d, {2.0}, {1.0}); - at25.rd_tracks_vcmax_ = true; - at25.update_temperature_dependent_params(25.0); - ok(old_shape.R_d_ < at25.R_d_, - "and it falls above the thermal optimum, as the old shape did"); - phylloptim::Leaf now45 = make_leaf(d, {2.0}, {1.0}); - now45.update_temperature_dependent_params(45.0); - ok(now45.R_d_ > at25.R_d_, "where the declining-Q10 form rises"); - } - } - - // ⚠️ The flag must be IN THE CACHE KEY. Flipping it on a leaf that has already - // been driven changes R_d at every temperature but 25 C and nothing else the - // key mentions, so a key that missed it would take a HIT here and silently run - // the whole comparison under whichever shape was seated first (hazard 10). - phylloptim::Leaf flipped = make_leaf(d, {2.0}, {1.0}); - flipped.update_temperature_dependent_params(40.0); - const double rd_new_shape = flipped.R_d_; - flipped.rd_tracks_vcmax_ = true; - flipped.set_physiology(fixture::root_network({1.0 / d.area_leaf}, {1.0}), - d.PPFD, {2.0}, {1.0}, d.K_s * d.theta / d.h, - d.atm_vpd, d.ca, 40.0, d.atm_o2_kpa, d.atm_kpa); - ok(flipped.R_d_ != rd_new_shape, - "setting rd_tracks_vcmax_ invalidates the temperature cache"); - - // Refused rather than resolved: the old shape has no reading in which a - // measured reference value means anything. - phylloptim::Leaf both = make_leaf(d, {2.0}, {1.0}); - both.rd_tracks_vcmax_ = true; - both.R_d_25 = 0.525; + l.R_d_25 = bad; bool threw = false; try { - both.update_temperature_dependent_params(30.0); + l.update_temperature_dependent_params(30.0); } catch (const std::runtime_error &) { threw = true; } - ok(threw, "rd_tracks_vcmax_ with a measured R_d_25 is refused, not resolved"); + ok(threw, "an unusable R_d_25 is refused, not worked around"); } - // ⚠️ THE LABEL BELOW SAID "Q10 = 2" AND THAT WAS STALE. A constant Q10 of 2 was - // the first implementation and was rejected on measurement (R_d 4.07 and -73% on - // A at 40 C, no operating point at all by 45 C); the "now" arm here is the - // shipped Tjoelker declining curve, which is what the numbers below describe. - // A printed label is not asserted by anything, so it outlived the thing it named. - printf(" blast radius on assimilation (old form vs declining Q10):\n"); + // The response, and the LIMIT it makes reachable, printed rather than asserted + // cell by cell: a higher R_d can drive net assimilation negative across the whole + // [gamma*, ca] bracket, and then there is no supply == demand root at all. At the + // defaults that happens by 45 C, which is a number a caller needs. + printf(" R_d and assimilation against leaf temperature:\n"); for (double T : {15.0, 25.0, 35.0, 40.0, 45.0}) { - double A_now = 0.0, Rd_now = 0.0; - bool now_ok = true; - try { - phylloptim::Leaf now = make_leaf(d, {2.0}, {1.0}); - now.update_temperature_dependent_params(T); - now.find_root_collar_psi(); - A_now = now.assim_colimited_; - Rd_now = now.R_d_; - } catch (const std::exception &) { - now_ok = false; - } - - double A_then = 0.0, Rd_then = 0.0; - bool then_ok = true; - try { - phylloptim::Leaf then = make_leaf(d, {2.0}, {1.0}); - then.rd_tracks_vcmax_ = true; - then.update_temperature_dependent_params(T); - then.find_root_collar_psi(); - A_then = then.assim_colimited_; - Rd_then = then.R_d_; - } catch (const std::exception &) { - then_ok = false; - } - - if (now_ok && then_ok) { - printf(" T = %4.1f C R_d %6.3f -> %6.3f A %8.4f -> %8.4f (%+.2f%%)\n", - T, Rd_then, Rd_now, A_then, A_now, - 100.0 * (A_now - A_then) / A_then); - } else { - printf(" T = %4.1f C old %s / new %s <-- no operating point\n", T, - then_ok ? "solves" : "THROWS", now_ok ? "solves" : "THROWS"); - } - if (T == 25.0) { - near(A_now, A_then, 1e-12, "the two forms agree exactly at 25 C"); - } + phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); + l.update_temperature_dependent_params(T); + l.find_root_collar_psi(); + printf(" T = %4.1f C R_d %6.3f A %8.4f%s\n", T, l.R_d_, + l.assim_colimited_, + l.ci_at_compensation_point_ ? " <-- shut down" : ""); } + // ⚠️ AND IT MUST SHUT DOWN RATHER THAN THROW. A leaf too hot to gain carbon at // any internal CO2 is a physical state, not a solver failure -- the energy-balance // path always treated it that way and the prescribed-temperature path used to @@ -2406,7 +2290,7 @@ void test_perturb_stem_b_matches_a_rebuild() { phylloptim::Leaf rebuilt = make_leaf(d, {2.0}, {1.0}); rebuilt.find_root_collar_psi(); rebuilt.set_traits(96.0, 2.680147, b_new, 5.870283, 2.680147, 3.898245, - 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRdDefault); + 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRd25); rebuilt.set_physiology(fixture::root_network(mrp, depth), d.PPFD, psi_soil, depth, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); @@ -2439,7 +2323,7 @@ void test_perturb_stem_b_matches_a_rebuild() { phylloptim::Leaf fresh = make_leaf(d, {2.0}, {1.0}); fresh.find_root_collar_psi(); rescaled.set_traits(96.0, 2.680147, 3.898245, 5.870283, 2.680147, 3.898245, - 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRdDefault); + 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRd25); rescaled.set_physiology(fixture::root_network(mrp, depth), d.PPFD, psi_soil, depth, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); @@ -2488,7 +2372,7 @@ void test_set_traits_matches_a_fresh_leaf() { phylloptim::Leaf reused = make_leaf(d, {2.0}, {1.0}); reused.find_root_collar_psi(); reused.set_traits(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], - t[10], t[11], t[12], kRdDefault); + t[10], t[11], t[12], kRd25); reused.set_physiology(fixture::root_network(mrp, depth), d.PPFD, psi_soil, depth, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); reused.find_root_collar_psi(); @@ -2518,7 +2402,7 @@ void test_set_traits_matches_a_fresh_leaf() { phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); const double vcmax_before = l.vcmax_; l.set_traits(96.0 * 2.0, 2.680147, 3.898245, 5.870283, 2.680147, 3.898245, - 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRdDefault); + 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRd25); std::vector mrp{1.0 / d.area_leaf}, psi_soil{2.0}, depth{1.0}; // The SAME leaf_temp and atm_o2_kpa, which is what arms the cache. l.set_physiology(fixture::root_network(mrp, depth), d.PPFD, psi_soil, depth, d.K_s * d.theta / d.h, @@ -2535,7 +2419,7 @@ void test_set_traits_matches_a_fresh_leaf() { phylloptim::Leaf l = make_leaf(d, {2.0}, {1.0}); const double E_before = l.transpiration(3.0, 1.0); l.set_traits(96.0, 2.680147, 3.898245 * 1.5, 5.870283, 2.680147, 3.898245, - 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRdDefault); + 5.870283, 1.5, 157.44, 0.30, 0.7, 0.99, 7.5, kRd25); std::vector mrp{1.0 / d.area_leaf}, psi_soil{2.0}, depth{1.0}; l.set_physiology(fixture::root_network(mrp, depth), d.PPFD, psi_soil, depth, d.K_s * d.theta / d.h, d.atm_vpd, d.ca, d.leaf_temp, d.atm_o2_kpa, d.atm_kpa); @@ -2563,7 +2447,7 @@ void test_set_traits_matches_a_fresh_leaf() { bool threw = false; try { l.set_traits(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], - t[10], t[11], t[12], kRdDefault); + t[10], t[11], t[12], kRd25); } catch (const std::runtime_error &) { threw = true; } diff --git a/tests/testthat/test-gradient-batch.R b/tests/testthat/test-gradient-batch.R index b521a19..bd37dbb 100644 --- a/tests/testthat/test-gradient-batch.R +++ b/tests/testthat/test-gradient-batch.R @@ -81,23 +81,13 @@ test_that("the parameter enumeration is the same order in R and in C++", { # integer positions into C++'s `phylloptim::gradient::par_names`, so appending # is safe and reordering would differentiate the wrong parameter and report # plausible numbers for it. Compared rather than trusted, in both directions. - # - # ⚠️ AND THE ENUMERATION IS NOT `leaf_traits()`' ORDER ANY MORE. `R_d_25` is a - # trait -- `set_traits()`' fourteenth argument -- but the enumeration APPENDS it - # after the two non-traits, because slotting it in at 13 would have displaced - # `par_kmax` and `par_resistance`, which is the reorder this comment warns about. - # So the two lists agree on the first thirteen and then deliberately diverge, and - # THAT is what is asserted: appending is the safe move and is what happened. - traits <- names(leaf_traits()) - r_side <- c(setdiff(traits, "R_d_25"), "leaf_specific_conductance_max", - "resistance", "R_d_25") + r_side <- c(names(leaf_traits()), "leaf_specific_conductance_max", + "resistance") expect_identical(gradient_par_names(), r_side) # And the count, which is what a positional trait call would silently break: - # thirteen traits, the two that are not traits, then R_d_25. + # fourteen traits then the two that are not traits. expect_length(gradient_par_names(), 16L) - expect_identical(gradient_par_names()[1:13], traits[1:13]) - expect_identical(gradient_par_names()[[16]], "R_d_25") - expect_identical(traits[[14]], "R_d_25") + expect_identical(gradient_par_names()[1:14], names(leaf_traits())) }) test_that("the batch reproduces leaf_gradient() bit-for-bit across the grid", { @@ -220,19 +210,10 @@ test_that("the recorded gradients have not moved", { # test-golden.R's first version made. libm's exp/pow are not bit-reproducible # between glibc on x86-64 and Apple's libm on arm64. # - # ⚠️ THIS FILE USED `golden_tolerance()` AND THAT WAS WRONG -- borrowed from the - # solved-output baseline, where it happened not to fail until #41 added a column. - # A gradient here is a FINITE DIFFERENCE, so it carries the solve's ~1e-9 floor - # DIVIDED BY THE STEP, and since the step is relative the amplification is set by - # the differentiated parameter's own magnitude. `R_d_25` is 1.44 where `vcmax_25` - # is 96, so it takes a 67x smaller absolute step and disagrees 10x more -- - # 1.3e-03 on Linux against 1.3e-04 for every column that was here before. - # `gradient_golden_tolerance()` is that measurement, with the arithmetic. - # - # The pre-existing columns were, and remain, in the golden file's own - # sqrt-amplified class: derivatives of outputs evaluated at the ARGMAX of a flat - # maximum, where a central difference cancels the systematic part of a libm - # difference but not all of it. + # THE TOLERANCE IS `gradient_golden_tolerance()`, not the solved-output one: a + # gradient here is a finite difference, so it carries the solve's floor divided by + # the step, and the smallest-magnitude parameter sets it for the whole file. See + # that function for the arithmetic. # # ⚠️ Read the SUMMARY LINE below for a magnitude, never the FAIL lines. The # figures in this package's guide were wrong twice because a truncated failure @@ -350,18 +331,8 @@ test_that("per-observation theta differentiates each row at its own parameters", }) b <- leaf_batch(psi_soil = psv, PPFD = 900) - # ⚠️ `R_d_25` LAST, and RESOLVED rather than left as its NA sentinel. A caller - # who builds `theta` themselves takes on the job `.gradient_theta_matrix()` does, - # and the contract is that theta holds the value the solve will USE: an NA there - # would leave each row's respiration derived from its own `vcmax_25`, so these - # rows would be differentiated at a different point than the `leaf_gradient()` - # references below -- which resolve it -- and the two would disagree by the - # respiration term rather than fail. The ratio comes off the leaf so there is no - # second copy of 0.015 in the tests either. - ratio <- b$leaf$rd_to_vcmax_ratio_ theta <- t(vapply(traits, function(tr) { - unname(c(unlist(tr)[gradient_par_names()[1:13]], 3.14e-5, NA_real_, - ratio * tr$vcmax_25)) + unname(c(unlist(tr)[gradient_par_names()[1:14]], 3.14e-5, NA_real_)) }, numeric(16))) g <- leaf_gradient_batch(b, theta = theta, pars = pars) diff --git a/tests/testthat/test-gradient.R b/tests/testthat/test-gradient.R index 7496260..440a01e 100644 --- a/tests/testthat/test-gradient.R +++ b/tests/testthat/test-gradient.R @@ -172,15 +172,11 @@ test_that("a pinned optimum takes the fallback, and the composite would be wrong expect_equal(dry$gradient["vcmax_25", "A"], 0.017548, tolerance = 1e-3) expect_equal(dry$gradient["stem_b", "A"], 4.6991, tolerance = 1e-3) - # ⚠️ THE `vcmax_25` NUMBER ABOVE WAS 0.014357 UNTIL #41, and the difference is - # not a change in the model -- it is which derivative the column reports. - # `R_d_25` is a parameter now, so `dA/dvcmax_25` is a PARTIAL at fixed - # respiration where it used to carry `ratio * dA/dR_d_25` too. Asserted as an - # identity rather than left as two unrelated recorded numbers, because that is - # what says the two columns still add up to the old one. - ratio <- leaf_model()$rd_to_vcmax_ratio_ + # `dA/dvcmax_25` is a PARTIAL at fixed respiration, since `R_d_25` is its own + # trait. A fit that wants respiration to follow Vcmax adds the two columns, so + # that combination is asserted rather than left implicit. expect_equal(dry$gradient["vcmax_25", "A"] + - ratio * dry$gradient["R_d_25", "A"], + 0.015 * dry$gradient["R_d_25", "A"], 0.014357, tolerance = 1e-3) }) @@ -220,24 +216,14 @@ test_that("a shut-down operating point reports no gradient and still differences # -- but the gradient itself is not all zero, because a shut-down leaf still # respires, so the fallback still has work to do. # - # ⚠️ WHICH PARAMETER CARRIES THAT IS THE SHARPEST TEST OF #41 IN THE SUITE, and - # it changed there. A = -R_d exactly at a shut-down point, so: - # - # before R_d was derived from vcmax_25, so dA/dvcmax_25 = -ratio = -0.015 - # and there was no R_d_25 column at all; - # now R_d_25 is a parameter, so dA/dR_d_25 = -1 and dA/dvcmax_25 = 0. - # - # The zero is EXACT and asserted as such: `vcmax_25` no longer reaches A here at - # all, so both perturbed solves return the same bits and their difference is a - # true zero rather than a small number. The -1 is not exact -- it is still a - # central difference of the solve -- and it lands within ~6e-11, which is the - # difference's own round-off and not a modelling residual. + # WHICH parameter carries it is the sharpest statement in the suite: `A = -R_d` + # exactly here, so `dA/dR_d_25` is -1 and `dA/dvcmax_25` is EXACTLY zero -- + # vcmax_25 does not reach A at all at a shut-down point, so both perturbed solves + # return the same bits. The -1 is a central difference and lands within ~6e-11. g <- grid_gradient(6.0, pars = c("vcmax_25", "stem_b", "R_d_25")) expect_identical(g$status, "no-gradient") expect_identical(g$method, "fd") - # A = -R_d, and at 25 C R_d IS the reference value. - expect_equal(g$value[["A"]], - -leaf_model()$rd_to_vcmax_ratio_ * leaf_traits()$vcmax_25) + expect_equal(g$value[["A"]], -leaf_traits()$R_d_25) expect_equal(g$gradient["R_d_25", "A"], -1, tolerance = 1e-8) expect_identical(g$gradient["vcmax_25", "A"], 0) expect_equal(g$gradient["stem_b", "A"], 0) @@ -623,10 +609,6 @@ test_that("the setter's positional trait call cannot drift in arity", { # fails to compile -- it would silently pass the wrong value for every argument # after the new one. So the arity is asserted here rather than trusted. # - # ⚠️ THIS TEST'S OWN PREDICTION CAME TRUE, and it is the reason the count is - # fourteen now. Adding `R_d_25` (#41) broke `.gradient_setter()` at run time and - # nowhere else, with "argument R_d_25 is missing" raised inside the generated - # binding -- a message naming neither the call nor the arity. expect_length(leaf_traits(), 14L) expect_length(formals(leaf_model()$set_traits), 14L) expect_identical(names(leaf_traits()), names(formals(leaf_model()$set_traits))) diff --git a/tests/testthat/test-surface.R b/tests/testthat/test-surface.R index 9499d22..2f432e4 100644 --- a/tests/testthat/test-surface.R +++ b/tests/testthat/test-surface.R @@ -17,14 +17,9 @@ test_that("leaf_traits() and leaf_control() partition the C++ constructor", { covered <- c(names(leaf_traits()), names(leaf_control())) expect_setequal(setdiff(ctor_args, covered), character(0)) - # ⚠️ `R_d_25` IS A TRAIT THE CONSTRUCTOR DOES NOT TAKE, and it is listed here so - # that stays a recorded fact rather than a surprise. `leaf_model()` assigns the - # field after construction; if it ever stopped doing so, `leaf_traits(R_d_25 =)` - # would be accepted and silently ignored, which is worse than not offering the - # argument -- and this test is not what would catch that (test-leaf-model.R's - # round trip is). Extending the generated constructor is the tidier fix and was - # not taken: its argument list is positional, seventeen long, and pinned by the - # raw-versus-friendly comparison below. + # `R_d_25` is a trait the constructor does not take: plant's own RcppR6 bindings + # pin this constructor by arity, so `leaf_model()` assigns the field afterwards. + # The test below checks that assignment really happens. expect_setequal(setdiff(covered, ctor_args), c("R_d_25", "integration_rule", "integration_tol")) expect_length(intersect(names(leaf_traits()), names(leaf_control())), 0) @@ -68,18 +63,10 @@ test_that("a non-default trait reaches the model through leaf_model()", { expect_lt(brittle$proportion_of_conductivity(2.0), leaf_model()$proportion_of_conductivity(2.0)) - # ⚠️ `R_d_25` NEEDS ITS OWN CASE, because it is the one trait the generated - # constructor does not take: `leaf_model()` assigns the field afterwards, and if - # that line went away every test above would still pass while - # `leaf_traits(R_d_25 =)` was accepted and silently ignored. See the partition - # test above for why the constructor was not extended instead. - # - # Both directions, and the sentinel too. The default derives R_d_25 as - # `rd_to_vcmax_ratio_ * vcmax_25`, so passing that product explicitly must be - # BIT-IDENTICAL to leaving it NA -- which is the check that the sentinel and the - # explicit route reach the same number rather than merely similar ones. - ratio <- leaf_model()$rd_to_vcmax_ratio_ - default_rd <- ratio * leaf_traits()$vcmax_25 + # ⚠️ `R_d_25` NEEDS ITS OWN CASE, because it is the one trait the constructor does + # not take: if `leaf_model()`'s assignment went away, every test above would still + # pass while `leaf_traits(R_d_25 = )` was accepted and silently ignored. + default_rd <- leaf_traits()$R_d_25 expect_identical( leaf_solve(psi_soil = 2.0, PPFD = 900, traits = leaf_traits(R_d_25 = default_rd))$A, @@ -90,13 +77,8 @@ test_that("a non-default trait reaches the model through leaf_model()", { expect_gt(leaf_solve(psi_soil = 2.0, PPFD = 900, traits = leaf_traits(R_d_25 = 0))$A, base$A) - - # And the sentinel is a value, not a hole: NA is accepted, a negative number is - # not, and neither is a vector -- `.check_scalars()` cannot cover this one - # because it demands finiteness. - expect_no_error(leaf_traits(R_d_25 = NA_real_)) expect_error(leaf_traits(R_d_25 = -1), "non-negative") - expect_error(leaf_traits(R_d_25 = c(1, 2)), "a single number") + expect_error(leaf_traits(R_d_25 = NA_real_), "finite") }) test_that("a control setting reaches the model and is not treated as a trait", { diff --git a/tests/testthat/test-temperature-response.R b/tests/testthat/test-temperature-response.R index bcee722..7e37de2 100644 --- a/tests/testthat/test-temperature-response.R +++ b/tests/testthat/test-temperature-response.R @@ -22,7 +22,9 @@ test_that("the temperature-response parameters are readable at their defaults", expect_equal(l$jmax_ha_, 30000) expect_equal(l$jmax_H_d_, 200000) expect_equal(l$jmax_d_S_, 650) - expect_equal(l$rd_to_vcmax_ratio_, 0.015) + expect_equal(l$R_d_25, 1.44) + expect_equal(l$rd_q10_intercept_, 3.09) + expect_equal(l$rd_q10_slope_, 0.0430) for (f in c("gamma_25_", "gamma_ha_", "kc_25_", "kc_ha_", "ko_25_", "ko_ha_")) { expect_true(is.finite(l[[f]]), info = f) @@ -76,59 +78,24 @@ test_that("changing a temperature parameter changes the solve, via set_traits", expect_gt(moved, base) }) -test_that("rd_to_vcmax_ratio_ reaches the solve", { +test_that("R_d_25 reaches the solve, and rises with temperature", { tr <- leaf_traits() - drive <- function(ratio) { - l <- leaf_model(traits = tr, control = leaf_control(), - supply = leaf_supply_single()) - if (!is.null(ratio)) l$rd_to_vcmax_ratio_ <- ratio - set_traits(l, tr) + drive <- function(rd_25, temp = 25) { + l <- leaf_model(traits = leaf_traits(R_d_25 = rd_25), + control = leaf_control(), supply = leaf_supply_single()) set_drivers(l, psi_soil = 0.5, PPFD = 1200, root_network = series_resistance(50), leaf_specific_conductance_max = 1e-4, atm_vpd = 1.0, ca = 40, - leaf_temp = 25, atm_o2_kpa = 20.9, atm_kpa = 101.325) + leaf_temp = temp, atm_o2_kpa = 20.9, atm_kpa = 101.325) l$find_root_collar_psi() - l$assim_colimited_ + c(A = l$assim_colimited_, R_d = l$R_d_) } - # More respiration, less net assimilation. Sabot's data imply ratios from - # 0.0046 to 0.0302 across species against the hard-coded 0.015, so this is the + # More respiration, less net assimilation. Sabot's data imply 0.44 to 2.90 + # umol m^-2 s^-1 across their 16 species against the 1.44 default, so this is the # range a calibration actually needs, not an extreme. - expect_lt(drive(0.0302), drive(0.0046)) -}) - -test_that("rd_tracks_vcmax_ restores the pre-#41 respiration shape from R", { - # ⚠️ THIS IS A REPRODUCIBILITY ESCAPE HATCH, NOT A MODELLING OPTION. `R_d` used to - # be `rd_to_vcmax_ratio_ * vcmax_(T)`, tracking Vcmax's PEAKED Arrhenius, and no - # combination of `rd_q10_intercept_` and `rd_q10_slope_` produces a peaked - # function -- so without this flag no published plant result computed under the - # old shape could be regenerated. The C++ suite pins the branch bit-exactly; what - # this test adds is that it is reachable from R at all, which is what the plant - # A/B needs. - rd_at <- function(temp, old_shape) { - l <- leaf_model() - l$rd_tracks_vcmax_ <- old_shape - set_drivers(l, psi_soil = 0.5, PPFD = 900, leaf_temp = temp) - c(R_d = l$R_d_, vcmax = l$vcmax_) - } - - ratio <- leaf_model()$rd_to_vcmax_ratio_ - for (temp in c(15, 25, 35, 45)) { - old <- rd_at(temp, TRUE) - expect_identical(old[["R_d"]], ratio * old[["vcmax"]], - label = sprintf("old shape at %g C", temp)) - } - - # The two shapes agree at the 25 C reference and diverge in OPPOSITE DIRECTIONS - # above the thermal optimum -- the peaked curve falls, the declining-Q10 curve - # rises. That opposition is the reason a flag was needed rather than a parameter. - expect_identical(rd_at(25, TRUE)[["R_d"]], rd_at(25, FALSE)[["R_d"]]) - expect_lt(rd_at(45, TRUE)[["R_d"]], rd_at(25, TRUE)[["R_d"]]) - expect_gt(rd_at(45, FALSE)[["R_d"]], rd_at(25, FALSE)[["R_d"]]) - - # And it is refused rather than resolved alongside a measured reference value. - l <- leaf_model(leaf_traits(R_d_25 = 0.525)) - l$rd_tracks_vcmax_ <- TRUE - expect_error(set_drivers(l, psi_soil = 0.5, PPFD = 900, leaf_temp = 30), - "not both") + expect_lt(drive(2.90)[["A"]], drive(0.44)[["A"]]) + # And the trait is the value AT 25 C: it is used verbatim there and larger above. + expect_equal(drive(0.525)[["R_d"]], 0.525) + expect_gt(drive(0.525, temp = 40)[["R_d"]], 0.525) }) diff --git a/tests/validate/rd_shape_arms.R b/tests/validate/rd_shape_arms.R deleted file mode 100644 index 6fee10b..0000000 --- a/tests/validate/rd_shape_arms.R +++ /dev/null @@ -1,138 +0,0 @@ -# The #41 respiration-shape revalidation, ON THE PLANT SIDE. -# -# Rscript tests/validate/rd_shape_arms.R -# -# The companion to rd_shape_grid.cpp, which does the same A/B on this package's own -# grid. This one runs plant, because plant is the consumer and an integrated -# demographic output is not predictable from a per-leaf one. -# -# ⚠️ DO NOT RUN THIS PINNED AT 25 C AND CALL IT REVALIDATED, which was the obvious -# temptation and is worthless. #41 is inert at 25 C BY CONSTRUCTION -- the -# respiration reference value is defined there -- so a bit-identical result at 25 C -# proves only that the reference point survived, which is a control and not a -# validation. The information is at the temperatures plant actually reaches. -# -# ⚠️ AND PLANT ITSELF PINS 25 C AT ITS DEFAULTS, which is the fact that decides how -# to read all of this. `TF24_Environment` sets `leaf_temp` as a CONSTANT extrinsic -# driver at 25, and `use_energy_balance` defaults to 0 (Tleaf = Tair). So at plant's -# default configuration #41 changes nothing, and that is provable rather than -# observed. The exposure is in the two configurations that leave 25 C: a -# non-default `leaf_temp` driver, and the Penman-Monteith path (plant #523). -# -# --- what was measured, 2026-08-10 -------------------------------------------- -# -# TF24 SCM offspring production, one species, max_patch_lifetime = 5: -# -# plant configuration phylloptim master this branch change -# default (leaf_temp = 25, PM off) 81.857087216483691 81.857087216483691 BIT-IDENTICAL -# leaf_temp driver = 30 C 24.283073719078399 22.369992929645893 -7.9% -# leaf_temp driver = 35 C 0.00021301630930330433 6.4471696967520308e-07 -99.7% (/331) -# Penman-Monteith energy balance on 2.2034981948510728 1.1638497249192270 -47.2% -# -# The PM row is the one to carry forward: it is where plant is heading, and #41 -# halves offspring production there. The 35 C row is a factor of 331, but on a -# population already four orders below replacement, so it is a large change to a -# number that was already saying "extinct". -# -# Leaf temperature on the PM path, over PAR {400,1000,2000} x Tair {20..40} x -# VPD {1,2,3}: Tleaf runs 19.1 to 62.0 C, i.e. up to +22 K ABOVE air temperature. -# That is why the PM arm moves so much more than its air temperature suggests -- -# a PM leaf at Tair 25 sits at 32.9 C, and mean A there falls 23%. -# -# ⚠️ On the PM path `Tleaf` ITSELF moved, on 22 of 90 cells. The energy balance -# couples to transpiration, so a change in R_d feeds back into leaf temperature -# rather than only into carbon. Do not treat leaf temperature as an input on that -# path. -# -# --- how to build the two arms ------------------------------------------------ -# -# Four installs: phylloptim twice and plant twice, because plant compiles -# phylloptim's headers in. ⚠️ `R_LIBS` FALLS BACK TO THE SITE LIBRARY SILENTLY if -# the intended one is not ready, which happened once while writing this and -# produced a plausible file describing the wrong package -- hence the hard check -# below, and print find.package() in anything you add. -# -# SP=/tmp/rd41; W=$(git rev-parse --show-toplevel) -# SITE=$(Rscript -e 'cat(.Library.site[[1]])') -# mkdir -p $SP/{lib-pm,lib-branch,lib-plant-master,lib-plant-branch} -# git -C $W archive origin/master | tar -x -C $SP/pm-src # mkdir first -# R_LIBS=$SITE R CMD INSTALL --no-docs -l $SP/lib-pm $SP/pm-src -# R_LIBS=$SITE R CMD INSTALL --no-docs -l $SP/lib-branch $W -# # plant, twice, from a CLEAN source copy each time -- a stale src/*.o is a -# # segfault that looks like a real bug (and would silently be the other arm) -# git -C ../plant archive --prefix=plant/ | tar -x -C $SP -# R_LIBS="$SP/lib-pm:$SITE" R CMD INSTALL --no-docs -l $SP/lib-plant-master $SP/plant -# # ...fresh copy, then... -# R_LIBS="$SP/lib-branch:$SITE" R CMD INSTALL --no-docs -l $SP/lib-plant-branch $SP/plant2 -# -# then run this script once per arm with R_LIBS set to that arm and EXPECT_LIB=$SP. -# -# plant needs no source change for this: it never calls `set_traits` (so the -# fourteenth argument is invisible to it) and binds only `R_d_` of the respiration -# fields. Checked against plant's inst/RcppR6_classes.yml. -# -# --- what this does NOT cover ------------------------------------------------- -# -# `compare_with_plant.R` compares against plant's OWN Leaf -- an independent -# implementation -- which is a stronger check than either arm here, and it still -# does not run. Its header blamed the constructor signature; that is no longer the -# obstacle. Against plant at 76df7169 the `Leaf()` and `set_physiology()` calls -# both work, and what actually stops it is that the reference has -# `root_collar_psi_` where this package has `opt_root_psi_` -- the #25 rename, -# which flipped the sign -- on top of results deliberately moved by #15, 11a, 11b, -# #25, #77 and #84. Reviving it is issue #64 and needs a decision about the -# reference, not a rename. Recorded here so the next attempt starts from the real -# obstacle. -suppressMessages(library(plant)) - -# ⚠️ HARD-FAIL ON THE WRONG LIBRARY, for the reason in the header. A warning would -# not do: every number below is plausible for either arm. -want <- Sys.getenv("EXPECT_LIB") -if (!nzchar(want)) { - stop("set EXPECT_LIB to the directory both packages must resolve inside") -} -for (pkg in c("plant", "phylloptim")) { - if (!startsWith(normalizePath(find.package(pkg)), normalizePath(want))) { - stop(pkg, " resolved outside ", want, ": ", find.package(pkg)) - } -} -cat("plant: ", find.package("plant"), "\n") -cat("phylloptim:", find.package("phylloptim"), "\n\n") - -# One SCM run. The setup is test-strategy-tf24.R's own regression case, so the -# default arm is comparable with a number plant already asserts. -offspring <- function(leaf_temp = NULL, energy_balance = FALSE) { - p0 <- scm_base_parameters("TF24") - p0$max_patch_lifetime <- 5 - p1 <- add_strategies(p0, trait_matrix(c(0.0825, 5), c("lma", "hmat")), - hyperpar = TF24_hyperpar, birth_rate = list(20)) - if (energy_balance) { - # ⚠️ THE FLAG LIVES IN `$pars`, and assigning it at the strategy's top level - # is accepted and silently ignored: `p1$strategies[[1]]$use_energy_balance <- - # 1` adds a list element nothing reads, and the run comes back EXACTLY equal - # to the default arm -- which reads as "PM changes nothing" rather than as a - # broken switch. Asserted rather than trusted. - st <- p1$strategies[[1]] - st$pars$use_energy_balance <- 1.0 - p1$strategies[[1]] <- st - stopifnot(p1$strategies[[1]]$pars$use_energy_balance == 1.0) - } - env <- Environment("TF24") - if (!is.null(leaf_temp)) { - env$extrinsic_drivers_set_constant("leaf_temp", leaf_temp) - } - run_scm(p1, env, Control())$offspring_production -} - -cases <- list( - list(label = "default (leaf_temp driver = 25, PM off)", temp = NULL, pm = FALSE), - list(label = "leaf_temp driver = 30", temp = 30, pm = FALSE), - list(label = "leaf_temp driver = 35", temp = 35, pm = FALSE), - list(label = "Penman-Monteith energy balance on", temp = NULL, pm = TRUE) -) -for (cs in cases) { - v <- offspring(cs$temp, cs$pm) - # %.17g, so the two arms can be compared bit-for-bit rather than to the 2e-2 - # the plant test uses -- the point of the default arm is exact equality. - cat(sprintf("%-40s %s\n", cs$label, paste(sprintf("%.17g", v), collapse = " "))) -} diff --git a/tests/validate/rd_shape_grid.cpp b/tests/validate/rd_shape_grid.cpp deleted file mode 100644 index 7b8f0de..0000000 --- a/tests/validate/rd_shape_grid.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// The #41 respiration-shape A/B, on this package's own grid. -// -// Three arms over the 1152 operating points of tests/cpp/golden/, differing only -// in which model computes them. It exists because the golden file can only say -// "something moved": this says WHICH of the four #41 commits moved it, by holding -// the shape fixed and letting everything else vary. -// -// arm model expectation -// master phylloptim at origin/master the reference -// branch this branch, default (declining Q10) moves off 25 C -// branch_old this branch, rd_tracks_vcmax_ = true bit-identical to master -// -// The third arm is the point. If it is bit-identical then the whole of #41 -- -// the cache key, the settable R_d_25, the shut-down exit, the R API -- is -// behaviour-neutral, and every difference in the second arm is the respiration -// shape and nothing else. Measured: 0 of 10368 cells differ. See PLAN item 41. -// -// ⚠️ ONE TREE, THREE BINARIES, as hazard 5 requires of any A/B here. The master -// arm is built from master's HEADERS against this file, not from master's own -// test_golden.cpp -- master's grid is 288 points at 25 C and would answer a -// different question. -// -// W=$(git rev-parse --show-toplevel) -// mkdir -p /tmp/ab && cd /tmp/ab -// cp $W/tests/cpp/root_network.hpp . -// git -C $W archive origin/master inst/include | tar -x --strip-components=2 \ -// -C master_inc # mkdir it first -// ODELIA=$(Rscript -e 'cat(system.file("include", package="odelia"))') -// BH=$(Rscript -e 'cat(system.file("include", package="BH"))') -// for arm in master branch branch_old; do -// case $arm in -// master) INC=master_inc; DEF="" ;; -// branch) INC=$W/inst/include; DEF="" ;; -// branch_old) INC=$W/inst/include; DEF="-DOLD_SHAPE" ;; -// esac -// c++ -std=c++20 -O2 -I. -I$INC -isystem $ODELIA -isystem $BH $DEF \ -// $W/tests/validate/rd_shape_grid.cpp -o grid_$arm -// ./grid_$arm > out_$arm.tsv -// done -// -// Then diff the TSVs. They are written with %.17g in the golden file's own column -// order, so `cmp` is a valid first pass and a per-field relative comparison is the -// second. ⚠️ Do NOT read them back with R's `read.delim` and compare as doubles -// without going through tests/validate/tsv_to_hex.c: R's decimal parser is not -// correctly rounded and perturbs about 18% of full-precision values, which is the -// mistake decision 1 in PLAN.md records. -// -// Not built by `make` or by CMake, and deliberately so: it needs two versions of -// the package at once, which no build in this repo can express. -#include - -#include "root_network.hpp" - -#include -#include -#include - -int main() { - // The golden grid's fixed drivers and axes, from tests/cpp/test_golden.cpp. - const double kTheta = 0.000157, kKs = 1.0, kH = 5.0, kAreaLeaf = 0.05; - const double kCa = 40.0, kO2 = 21.0, kPatm = 101.3; - const double temps[] = {15.0, 25.0, 35.0, 40.0}; - const double psi_soils[] = {0.5, 1.0, 2.0, 3.0, 4.0, 6.0}; - const double ppfds[] = {100.0, 500.0, 900.0, 1500.0}; - const double vpds[] = {0.5, 1.0, 2.0, 4.0}; - const int layer_counts[] = {1, 3, 5}; - - printf("psi_soil\tppfd\tvpd\tleaf_temp\tlayers\tpsi_stem\topt_root_psi\tci\t" - "assim\ttranspiration\tgc\tprofit\te_up\tuptake\n"); - for (double t : temps) { - for (double p : psi_soils) { - for (double q : ppfds) { - for (double v : vpds) { - for (int n : layer_counts) { - phylloptim::Leaf l; - l.setup_transpiration(100); - l.setup_root_vulnerability(100); -#ifdef OLD_SHAPE - // ⚠️ The whole reason this arm exists. Absent on master, where the - // shape is unconditional -- so `-DOLD_SHAPE` must never be combined - // with master's headers, and the compiler will say so. - l.rd_tracks_vcmax_ = true; -#endif - std::vector ps(n), depth(n), root(n); - for (int i = 0; i < n; ++i) { - ps[i] = p + 0.25 * i; - depth[i] = 1.0 * (i + 1); - root[i] = 1.0 / n / kAreaLeaf; - } - l.set_physiology(fixture::root_network(root, depth), q, ps, depth, - kKs * kTheta / kH, v, kCa, t, kO2, kPatm); - l.find_root_collar_psi(); - double uptake = 0.0; - for (double s : l.soil_consumption_) { - if (std::isfinite(s)) { - uptake += s; - } - } - printf("%.17g\t%.17g\t%.17g\t%.17g\t%d", p, q, v, t, n); - for (double x : {l.opt_psi_stem_, l.opt_root_psi_, l.ci_, - l.assim_colimited_, l.transpiration_, - l.stom_cond_CO2_, l.profit_, l.E_up_, uptake}) { - printf("\t%.17g", x); - } - printf("\n"); - } - } - } - } - } - return 0; -} From f18ea3660b23ca0842fd67b3e2b3bcf49a6d6f4d Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Tue, 11 Aug 2026 06:57:21 +1000 Subject: [PATCH 12/13] Record how the plant A/B was run (#41) PLAN 41 quotes offspring-production numbers from a two-build comparison with no harness behind it, so the recipe goes next to them: two phylloptim libraries, two plant installs from clean sources, and a hard find.package() check because R_LIBS falls back to the site build in silence. Co-Authored-By: Claude Opus 5 (1M context) --- PLAN.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/PLAN.md b/PLAN.md index 8211c66..7b93928 100644 --- a/PLAN.md +++ b/PLAN.md @@ -561,6 +561,15 @@ A study that wants respiration to track Vcmax should say so in its own parameterisation — plant's `TF24_hyperpar` is where every other derived parameter is computed. +**How that A/B was run**, since `compare_with_plant.R` cannot do it (below) and there +is no harness for it: install phylloptim twice (`origin/master` and the branch) into +separate libraries, then install plant twice from a **clean** source copy each time +with `R_LIBS` pointing at one phylloptim library and the site library — a stale +`src/*.o` would silently give you the other arm — and run the same script under each, +with `leaf_temp` and `vcmax_25` varied. ⚠️ Print and CHECK `find.package()` for both +packages in the script: `R_LIBS` falls back to the site build without a word, which +happened here and produced a plausible file describing the wrong package. + ⚠️ **The golden file was blind to all of this** — 288 points at one temperature, where every reference value is defined. It now carries a 40 °C block as well. From 22d412b6295dd5a352af3cfcb2d3196e0a1abad7 Mon Sep 17 00:00:00 2001 From: Daniel Falster Date: Tue, 11 Aug 2026 07:15:28 +1000 Subject: [PATCH 13/13] Update the numbers the last two commits left stale (#41) Three edits from the previous round never landed -- they ran from a drifted working directory -- so the developer guide still described a 1152-point golden grid at four temperatures, and both vignettes still described R_d_25 as an appended parameter with a NaN sentinel. Redone, and this time swept for every count rather than the ones I remembered: 1152 / 10368 -> 576 / 5184, from CI's own summary line "4 leaf temperatures" -> 25 and 40 C thirteen traits -> fourteen, in nine files "A character vector of fifteen names" -> sixteen (src/gradient.cpp) "all 13 traits" in bench_gradient -> "13 of the 14", which is what it measures; R_d_25 needs no rebuild and adds nothing to the cheap/rebuild split the temperature-response block binds fifteen fields now, not thirteen Also cuts the history the review flagged in the golden-file section: the "it was 288 points until #41" paragraph, the 1.82e-07 retraction, and the sqrt-story archaeology are gone, leaving the mechanism and the current figures. 486 C++ checks, golden bit-identical, 933 R checks, R CMD check 1 pre-existing NOTE, bench builds. Co-Authored-By: Claude Opus 5 (1M context) --- .claude/CLAUDE.md | 92 ++++++++-------------- PLAN.md | 10 +-- R/RcppExports.R | 4 +- R/gradient.R | 4 +- inst/RcppR6_classes.yml | 4 +- inst/include/phylloptim/leaf_model.hpp | 17 ++-- src/gradient.cpp | 4 +- tests/cpp/bench_gradient.cpp | 18 +++-- tests/cpp/bench_solve.cpp | 15 ++-- tests/cpp/test_golden.cpp | 18 ++--- tests/cpp/test_leaf.cpp | 2 +- tests/testthat/test-gradient-batch.R | 4 +- tests/testthat/test-temperature-response.R | 2 +- tools/gradient_golden.R | 8 +- vignettes/cpp-interface.Rmd | 20 ++--- vignettes/phylloptim.Rmd | 11 +-- 16 files changed, 95 insertions(+), 138 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 2e9f8f4..37f3843 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -72,8 +72,8 @@ tests/cpp/ plain-C++ suite, no R, no framework tests/cpp/root_network.hpp the suite's root-architecture fixture: the two ex-Leaf-default beta_R_* constants, in ONE place because the golden file's bit-exactness depends on them -tests/cpp/golden/ bit-exact regression baseline, 1152 operating points - -- the 288-point state grid at 4 leaf temperatures +tests/cpp/golden/ bit-exact regression baseline, 576 operating points + -- one 288-point state grid at 25 and 40 C tests/cpp/bench_solve.cpp timing harness for the collar solve (hazard 5) tests/cpp/bench_gradient.cpp timing harness for a TRAIT GRADIENT: the IFT composite against differencing the solve, with @@ -280,23 +280,20 @@ while looking like history. Two rows were produced that way before it was notice ## The golden file is the safety net — treat it that way -`tests/cpp/golden/operating_points.tsv` records 1152 operating points and is -compared **bit-exactly** (`%.17g` round-trips a double). It is what makes a large -refactor of this code checkable rather than hopeful, and it earned that role -repeatedly: it proved three "surely dead" `set_physiology` arguments really were -dead, confined the shutdown fix to exactly 48 rows × 5 fields, and showed the -`area_leaf` change was 2 ULP. - -⚠️ **It was 288 points until #41, all at one leaf temperature, and that made it -blind to every temperature response in the model.** The reference values of Vcmax, -Jmax and R_d are *defined* at 25 °C, so a change to any response curve is inert -there **by construction** — #41 changed R_d's shape at every temperature except -25 °C and the file did not move a bit. It is now the same 288-point state grid at -15 / 25 / 35 / 40 °C, with temperature as the OUTERMOST loop so the 25 °C block -stayed byte-identical through the regeneration. Read a bit-identical run -accordingly: it is evidence about the temperature responses now and it was not -before — and the classification it prints is per temperature, because points move -between branches as the leaf warms (dry-pinned 18 → 0, wet-pinned 24 → 80). +`tests/cpp/golden/operating_points.tsv` records 576 operating points — one +288-point state grid at 25 and 40 °C — and is compared **bit-exactly** (`%.17g` +round-trips a double). It is what makes a large refactor of this code checkable +rather than hopeful, and it earned that role repeatedly: it proved three "surely +dead" `set_physiology` arguments really were dead, confined the shutdown fix to +exactly 48 rows × 5 fields, and showed the `area_leaf` change was 2 ULP. + +⚠️ **A grid at one leaf temperature is blind to every temperature response in the +model**, because every reference value is *defined* at 25 °C and a change to any +response curve is inert there **by construction**. Hence the second temperature, and +hence the classification being printed per temperature: points move between branches +as the leaf warms (dry-pinned 18 → 0, wet-pinned 24 → 80). Temperature is the +OUTERMOST loop, which is what lets a regeneration that adds one be checked as an +addition — the 25 °C block must come out byte-identical. **Only run `make golden` deliberately.** Running it after an accidental change rubber-stamps the change. If a diff is intended, regenerate and say so in the @@ -354,46 +351,23 @@ magnitude apart: | `profit` | **2.14e-09** | **2.14e-09** | it is the maximum itself — well-conditioned | | the other eight | **1.4e-04** | **1.4e-04** | evaluated at the **argmax** — sqrt-amplified | -Read off CI's summary line on the 1152-point grid, 7702 of 10368 values differing, -against tolerances of 1e-05 and 5e-03. - -⚠️ **The `profit` row said 1.82e-07 until #41 and that was stale, not superseded by -the bigger grid.** A grid can only move a *maximum* upward, and the 25 °C block is -byte-identical — so the improvement is a change to the model on `master` since the -figure was recorded (#77 and #84 are the candidates), and it is NOT attributed here -because doing so needs a cross-platform run of master, which no macOS box can give -you. Take the lesson rather than the number: **this table is a CI reading, and it -goes stale silently because nothing asserts it.** Read the summary line. - -**These figures also changed when PLAN 11a replaced the collar solver, and how they -changed is informative.** They were `profit` 1.85e-06 / 5.87e-07 and the other -eight 5.53e-04 / 2.73e-04. Two things to take from the move: - -- **The gcc-versus-clang split was itself a golden-section artefact.** The two - compilers now report *identical* figures, where they used to differ by 2–3×. What - differed between them was which way a golden-section comparison fell; what is - left is libm's `exp`/`pow`, which is a property of the platform and not of the - compiler. So do not expect a compiler-dependent column here any more — and if one - reappears, something has reintroduced a discrete decision into the solve. -- **The sqrt story fits, but no longer tightly.** At 11a it was `sqrt(1.85e-06)` ≈ - 1.4e-03 against 5.5e-04 observed, then `sqrt(1.82e-07)` ≈ 4.3e-04 against - 1.4e-04 — same order, with the residual factor shrinking as expected once the - argmax stopped carrying an extra `GSS_tol_abs` of arbitrary displacement. It does - NOT survive the current pair: `sqrt(2.14e-09)` ≈ 4.6e-05 against 1.4e-04 - observed, which is three times the other way. ⚠️ Do not read that as a broken - identity — it never was one. The two column maxima fall at *different* operating - points, and the argmax column now has 864 hot rows the profit column's worst case - is not among. `sqrt(worst profit)` is a sanity check on the mechanism, not a - prediction of `worst argmax`. - -The maximum is *flat*: curvature measured directly at the two worst points gives -k ≈ 1.0 and 0.9 in `profit ≈ p* − k(psi_stem−x*)²`. For a flat maximum an error -`dp` in the profit **value** displaces its **location** by `sqrt(dp/k)`, which is -why the well-conditioned column sits three orders below the other. Checked -pointwise — at those points the residuals imply k = 1.01 and 1.70 against the 1.0 -and 0.9 measured from the curvature. It is *not* a global identity: the two column -maxima fall at different operating points, so `sqrt(worst profit)` is not meant to -reproduce `worst argmax`. +Read off CI's summary line: 3757 of 5184 values differ, against tolerances of 1e-05 +and 5e-03. ⚠️ **This table is a CI reading and nothing asserts it, so it goes stale +silently** — it has been wrong three times. Read the summary line, never the FAIL +lines, which are truncated at 20 and biased toward whichever rows come first. + +gcc and clang report *identical* figures. They used to differ by 2–3×, and what +differed was which way a golden-section comparison fell; since PLAN 11a removed that +search, what is left is libm's `exp`/`pow` — a property of the platform, not the +compiler. If a compiler-dependent column reappears, something has reintroduced a +discrete decision into the solve. + +**Why the two classes are five orders apart:** the maximum is *flat*, with curvature +k ≈ 1.0 measured directly at the worst points in `profit ≈ p* − k(psi_stem−x*)²`, so +an error `dp` in the profit **value** displaces its **location** by `sqrt(dp/k)`. +That is a mechanism, not an identity — `sqrt(2.14e-09)` ≈ 4.6e-05 against the 1.4e-04 +observed, because the two column maxima fall at *different* operating points. Do not +expect `sqrt(worst profit)` to predict `worst argmax`. Two things follow that matter beyond this file: diff --git a/PLAN.md b/PLAN.md index 7b93928..6cb9f4b 100644 --- a/PLAN.md +++ b/PLAN.md @@ -920,8 +920,9 @@ actually need, not to police one you could remove.** Done in #15: five dead entities removed and `set_physiology` taken 14 → 11 arguments, three further dead constants deleted, and **thirteen** temperature-response -parameters made settable. ⚠️ One of those, `rd_to_vcmax_ratio_`, is settable in C++ -but **not bound to R** — that is #41, and this item overstated it. +parameters made settable in C++. ⚠️ One of those, `rd_to_vcmax_ratio_`, was never +bound to R — item 41, which resolved it by deleting the parameter rather than +binding it. Fifteen are bound now. `area_leaf` is out of the supply contract, not merely out of `set_physiology`. Why that was safe is a **homogeneity property** rather than a coincidence: every term in @@ -1376,9 +1377,8 @@ established with `stem_b` first. ⚠️ **And the golden file could not have been the regression guard anyway.** It is compared with a 1e-3 tolerance off macOS/arm64 and the defect was 3.4e-5, so a recurrence would pass on Linux. The guard is a test that compares two orderings **in -the same process**, which is exact everywhere and needs no tolerance — all thirteen -traits as predecessors, four permutations, both routes, both `fast_stem_curve` -settings. +the same process**, which is exact everywhere and needs no tolerance — every trait +as a predecessor, four permutations, both routes, both `fast_stem_curve` settings. ### And what it unblocks diff --git a/R/RcppExports.R b/R/RcppExports.R index 04454f5..bffcb1a 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -759,13 +759,13 @@ Leaf__g1_eff__get <- function(obj_) { #' The differentiable parameters, in the order C++ indexes them #' -#' The thirteen [leaf_traits()] in `set_traits()`'s argument order, then +#' The fourteen [leaf_traits()] in `set_traits()`'s argument order, then #' `leaf_specific_conductance_max` and `resistance`. Exported so that R's own #' copy of this order can be compared against it in a test: R passes integer #' positions into this enumeration, so appending to it is safe and reordering it #' would silently differentiate the wrong parameter. #' -#' @return A character vector of fifteen names. +#' @return A character vector of sixteen names. #' @seealso [leaf_gradient_batch()] #' @examples #' gradient_par_names() diff --git a/R/gradient.R b/R/gradient.R index 920406b..a3e6580 100644 --- a/R/gradient.R +++ b/R/gradient.R @@ -620,7 +620,7 @@ leaf_gradient <- function(psi_soil, # Everything this can differentiate, and its current value, as one named vector. # -# The thirteen traits, plus the two quantities a calibration fits that are NOT +# The fourteen traits, plus the two quantities a calibration fits that are NOT # traits (#44) and that `pars` therefore used to reject: # # * `leaf_specific_conductance_max` -- a DRIVER, set through set_drivers(). It @@ -714,7 +714,7 @@ leaf_gradient <- function(psi_soil, } # Positional, straight onto the object, rather than through `set_traits()` and # `set_drivers()`. Those two rebuild a `leaf_traits` object with - # `structure(as.list(...))`, re-extract thirteen fields by name, and re-run the + # `structure(as.list(...))`, re-extract fourteen fields by name, and re-run the # driver validation -- 3.0% + 3.3% + 4.9% of a gradient's self time between them, # for work whose answer cannot change across perturbations. # diff --git a/inst/RcppR6_classes.yml b/inst/RcppR6_classes.yml index f295715..4af1b02 100644 --- a/inst/RcppR6_classes.yml +++ b/inst/RcppR6_classes.yml @@ -156,9 +156,7 @@ Leaf: # # The eight fields above are DERIVED: set_physiology recomputes them from # leaf temperature on every call, so writing one from R is overwritten by - # the next solve. These thirteen are the parameters that generate them, and - # they were public C++ members with no entry here at all -- so from R the - # shape of the temperature response was fixed and unreachable. + # the next solve. These fifteen are the parameters that generate them. # # ⚠️ That is not a small gap. The defaults imply a thermal optimum near # 31.2 C for Vcmax and 27.9 C for Jmax (Topt = H_d / (d_S - R*log(ha/(H_d - diff --git a/inst/include/phylloptim/leaf_model.hpp b/inst/include/phylloptim/leaf_model.hpp index 4e8a232..8c7eae0 100644 --- a/inst/include/phylloptim/leaf_model.hpp +++ b/inst/include/phylloptim/leaf_model.hpp @@ -481,13 +481,14 @@ class Leaf { // check here can see the difference, because both are just positive numbers. void set_physiology(const RootNetwork& root_network, double PPFD, const std::vector& psi_soil, const std::vector& soil_depth, double leaf_specific_conductance_max, double atm_vpd, double ca, double leaf_temp, double atm_o2_kpa, double atm_kpa); - // Replace the thirteen traits on an existing Leaf, leaving the four numerical - // controls alone. Same arguments, same order, as the constructor's trait subset. - // - // It was fifteen before #33. `beta_R_H` and `beta_R_V` left with the root - // architecture model, so they are no longer traits of anything here and there is - // no route to d(output)/d(beta_R_*) through this object. A caller who needs one - // differences the NETWORK, which is now an input: root_network_from_carbon is + // Replace the fourteen traits on an existing Leaf, leaving the four numerical + // controls alone. Same arguments, same order, as the constructor's trait subset, + // plus R_d_25 which the constructor does not take. + // + // `beta_R_H` and `beta_R_V` are NOT traits here since #33: they left with the root + // architecture model, so there is no route to d(output)/d(beta_R_*) through this + // object. A caller who needs one differences the NETWORK, which is now an input: + // root_network_from_carbon is // homogeneous of degree 1 in each constant (r_R_H_min proportional to beta_R_H, // r_R_V to beta_R_V), so the perturbed network is a scaling of the base one and // costs no rebuild -- but the two solves either side of it are still two solves. @@ -1191,7 +1192,7 @@ inline void Leaf::check_psi_magnitudes(double psi_crit, double stem_b, } } -// See the header for why this exists rather than fifteen settable fields. +// See the header for why this exists rather than fourteen settable fields. inline void Leaf::set_traits(double vcmax_25_, double stem_c_, double stem_b_, double psi_crit_, double root_c_, double root_b_, double root_psi_crit_, double beta2_, diff --git a/src/gradient.cpp b/src/gradient.cpp index 791bbe2..cbcedce 100644 --- a/src/gradient.cpp +++ b/src/gradient.cpp @@ -55,13 +55,13 @@ DriverBatch* checked(SEXP drivers) { //' The differentiable parameters, in the order C++ indexes them //' -//' The thirteen [leaf_traits()] in `set_traits()`'s argument order, then +//' The fourteen [leaf_traits()] in `set_traits()`'s argument order, then //' `leaf_specific_conductance_max` and `resistance`. Exported so that R's own //' copy of this order can be compared against it in a test: R passes integer //' positions into this enumeration, so appending to it is safe and reordering it //' would silently differentiate the wrong parameter. //' -//' @return A character vector of fifteen names. +//' @return A character vector of sixteen names. //' @seealso [leaf_gradient_batch()] //' @examples //' gradient_par_names() diff --git a/tests/cpp/bench_gradient.cpp b/tests/cpp/bench_gradient.cpp index 3bb3838..ea294a3 100644 --- a/tests/cpp/bench_gradient.cpp +++ b/tests/cpp/bench_gradient.cpp @@ -12,8 +12,8 @@ // distinction matters because **plant links these headers directly**. So the // arithmetic has to be done again with the boundary removed, which is what this // measures. PLAN 11e records the answer; the short version is that the composite -// does win here, by rather less than 12x, and for four of the fifteen traits by -// almost nothing at all -- for a reason neither 11d nor 11e anticipated. +// does win here, by rather less than 12x, and for four of the traits by almost +// nothing at all -- for a reason neither 11d nor 11e anticipated. // // WHAT THE TWO ARMS ARE. Both perturb one trait by a relative 1e-6 either side // and both pay set_traits + set_physiology per perturbation, because a trait @@ -55,11 +55,13 @@ namespace { // The default trait vector, in set_traits' argument order. -// Thirteen, not fifteen: beta_R_H and beta_R_V left with the root-architecture -// model in #33. They were two of the four traits whose gradient is 100% -// argmax-mediated, and a gradient in either is now taken where the network is -// built -- exactly, because root_network_from_carbon is homogeneous of degree 1 -// in each. +// +// Thirteen of the fourteen traits: `R_d_25` is left at its default because it needs +// no spline rebuild and so lands in the cheap bucket, which the split below already +// has twelve examples of. `beta_R_H` and `beta_R_V` are not here at all -- they left +// with the root-architecture model in #33, and a gradient in either is now taken +// where the network is built, exactly, because root_network_from_carbon is +// homogeneous of degree 1 in each. struct Traits { double v[13]; }; @@ -276,7 +278,7 @@ int main(int argc, char **argv) { } } - printf("\n all 13 traits FD %8.1f us IFT %8.1f us %.2fx\n", + printf("\n 13 of the 14 traits FD %8.1f us IFT %8.1f us %.2fx\n", fd_all, ift_all, fd_all / ift_all); printf(" the %2d with no rebuild FD %8.1f us IFT %8.1f us %.2fx\n", n_cheap, fd_cheap, ift_cheap, fd_cheap / ift_cheap); diff --git a/tests/cpp/bench_solve.cpp b/tests/cpp/bench_solve.cpp index bbb7744..9b557e9 100644 --- a/tests/cpp/bench_solve.cpp +++ b/tests/cpp/bench_solve.cpp @@ -9,15 +9,14 @@ // and gets a different answer). // // Workload is 288 operating points over psi_soil, PPFD, VPD and 1/3/5 soil layers, -// all at a leaf temperature of 25 C, shutdown corner included. +// all at a leaf temperature of 25 C, shutdown corner included -- the golden grid's +// state axes, at its reference temperature. // -// ⚠️ That WAS the golden-file grid and is now a subset of it: #41 gave the golden -// grid a temperature axis (4 temperatures, 1152 points) and this harness -// deliberately did not follow. A timing baseline is only useful against its own -// history -- tools/cost-baseline.tsv and tools/bench_history.sh compare across -// commits -- and quadrupling the workload would end that history to measure nothing -// new about the solve. If a temperature-dependent cost ever needs measuring, add a -// second workload rather than growing this one. +// ⚠️ It deliberately does NOT follow the golden grid's temperature axis. A timing +// baseline is only useful against its own history (tools/cost-baseline.tsv, +// tools/bench_history.sh), so doubling the workload would end that history to +// measure nothing new about the solve. If a temperature-dependent cost ever needs +// measuring, add a second workload rather than growing this one. // // Reports min-of-N, not mean. This is a deterministic computation on a noisy // machine, so the minimum is the least-contaminated estimate of its cost; the diff --git a/tests/cpp/test_golden.cpp b/tests/cpp/test_golden.cpp index 6f58a0d..eaec452 100644 --- a/tests/cpp/test_golden.cpp +++ b/tests/cpp/test_golden.cpp @@ -483,9 +483,9 @@ int compare(Tolerance tol) { // platform is NOT the fix -- it just moves the failure to the first one. // // The interesting part is the SIZE of the disagreement, because it is not one -// number. Read off this program's own summary line on Linux CI over the 1152-point -// grid, the nine reported fields split into two classes five orders of magnitude -// apart, and gcc and clang now agree exactly: +// number. Read off this program's own summary line on Linux CI, the nine reported +// fields split into two classes five orders of magnitude apart, and gcc and clang +// agree exactly: // // gcc clang // profit 2.14e-09 2.14e-09 @@ -493,14 +493,10 @@ int compare(Tolerance tol) { // transpiration, gc, e_up, // uptake 1.4e-04 1.4e-04 // -// ⚠️ THOSE NUMBERS READ 1.85e-06 / 5.87e-07 AND 5.53e-04 / 2.73e-04 UNTIL #41 -- -// two generations stale, and still carrying a gcc-versus-clang split that PLAN 11a -// removed (it was which way a golden-section comparison fell; what is left is libm, -// a property of the platform and not the compiler). Nothing asserts this comment, -// so it rots in silence. **If you need a magnitude, read the summary line above the -// FAIL lines, not this block and not the FAIL lines** -- the truncated failure list -// is biased toward whichever rows come first, which is how the figure in the -// developer guide came to be wrong twice. +// ⚠️ NOTHING ASSERTS THAT BLOCK, so it rots in silence -- it has been wrong three +// times. **If you need a magnitude, read the summary line, not this comment and not +// the FAIL lines**: the failure list is truncated at 20 and biased toward whichever +// rows come first. // // That split is structural, not luck. `find_root_collar_psi` maximises profit // over the collar potential, and the maximum is FLAT: curvature k measured diff --git a/tests/cpp/test_leaf.cpp b/tests/cpp/test_leaf.cpp index a29766d..e0c0dd7 100644 --- a/tests/cpp/test_leaf.cpp +++ b/tests/cpp/test_leaf.cpp @@ -777,7 +777,7 @@ void test_collar_solve_handles_a_pinned_optimum() { // bit-identical golden run says nothing here. The sequence below alternates kinds // on purpose, so an unwritten tag reads as the step before it. // -// The count check over the whole 1152-point grid lives in test_golden.cpp; this is +// The count check over the whole golden grid lives in test_golden.cpp; this is // the other half -- that every path writes, and that the tag comes from the // branch rather than from the numbers. void test_operating_point_kind_is_written_by_every_path() { diff --git a/tests/testthat/test-gradient-batch.R b/tests/testthat/test-gradient-batch.R index bd37dbb..c421d7a 100644 --- a/tests/testthat/test-gradient-batch.R +++ b/tests/testthat/test-gradient-batch.R @@ -450,8 +450,8 @@ test_that("`pars` order does not change any gradient (#72)", { # ⚠️ And the predecessor that made the defect WORST, which is not the one you # would pick by eye: `a` = 0.30 and `curv_fact_colim` = 0.99 take the absolute # 1e-6 step floor rather than a relative step, and `stem_c`'s perturbation - # REBUILDS the very curve the `stem_b` shortcut then rescales. Each of the - # thirteen is checked as a predecessor rather than a sample of them. + # REBUILDS the very curve the `stem_b` shortcut then rescales. Every trait is + # checked as a predecessor rather than a sample of them. solo <- leaf_gradient_batch(b, pars = "stem_b")$gradient[1, "stem_b", ] for (p in setdiff(names(leaf_traits()), "stem_b")) { got <- leaf_gradient_batch(b, pars = c(p, "stem_b"))$gradient[1, "stem_b", ] diff --git a/tests/testthat/test-temperature-response.R b/tests/testthat/test-temperature-response.R index 7e37de2..993a5a5 100644 --- a/tests/testthat/test-temperature-response.R +++ b/tests/testthat/test-temperature-response.R @@ -1,6 +1,6 @@ # The temperature-response parameters, now reachable from R. # -# WHY THIS FILE EXISTS. These thirteen were public C++ members with no entry in +# WHY THIS FILE EXISTS. These fifteen were public C++ members with no entry in # inst/RcppR6_classes.yml, so from R the SHAPE of the temperature response was # fixed and unreachable. The eight derived quantities (vcmax_, jmax_, gamma_, # ko_, kc_, km_, R_d_, electron_transport_) were bound and settable, which made diff --git a/tools/gradient_golden.R b/tools/gradient_golden.R index 77ac6b1..d2671b1 100644 --- a/tools/gradient_golden.R +++ b/tools/gradient_golden.R @@ -64,11 +64,9 @@ grid_drivers <- function(psi_soil, ppfd = 900, vpd = 2.0, layers = 1L) { # interior optimum and the fallback must return ~1.26 at a dry-pinned one. A pin # that omitted it would miss the sharpest statement of why there are two routes. # -# `R_d_25` is in `pars` throughout for the opposite reason: it is the newest -# parameter (#41) and the one with no history in this file, so every row records -# it. It also makes each row's `vcmax_25` entry checkable rather than merely -# recorded -- `dY/dvcmax_25 + rd_to_vcmax_ratio_ * dY/dR_d_25` is the total -# derivative the `vcmax_25` column used to hold on its own. +# `R_d_25` is in `pars` throughout because it is the smallest-magnitude parameter +# here, so it takes the smallest absolute step and sets this file's cross-platform +# tolerance -- see `gradient_golden_tolerance()`. cases <- list( list(label = "interior-1layer", args = grid_drivers(2.0), diff --git a/vignettes/cpp-interface.Rmd b/vignettes/cpp-interface.Rmd index 7b08d3b..9f95151 100644 --- a/vignettes/cpp-interface.Rmd +++ b/vignettes/cpp-interface.Rmd @@ -120,7 +120,7 @@ d.root_network = roots; d.PPFD = 900; d.psi_soil = {2.0}; d.soil_depth = {1.0}; d.atm_vpd = 2.0; d.ca = 40.0; d.leaf_temp = 25.0; d.atm_o2_kpa = 21.0; d.atm_kpa = 101.3; -double theta[g::n_pars] = {/* 13 traits, then kmax, then resistance */}; +double theta[g::n_pars] = {/* 14 traits, then kmax, then resistance */}; const int pars[1] = {0}; // g::par_names()[0] == "vcmax_25" phylloptim::Leaf l; @@ -130,18 +130,12 @@ const std::vector out = // out[i].status is Interior / Pinned / NoGradient / Error ``` -`theta` is `g::n_pars` = 16 doubles: the first thirteen traits in `set_traits`' -argument order, then `leaf_specific_conductance_max`, then the single-potential -path's `resistance`, then `R_d_25`. `g::par_names()` is that order, and `pars` holds -positions into it — ⚠️ appending to the enumeration is safe and reordering it is -not, which is why `R_d_25` sits at the end (`g::par_R_d_25` = 15) rather than at 13 -where `set_traits` takes it: slotting it in would have displaced `g::par_kmax` and -`g::par_resistance`. - -⚠️ **Do not put `set_traits`' NaN sentinel in `theta`.** `R_d_25` may be NaN as a -trait, meaning *derive it from `rd_to_vcmax_ratio_ * vcmax_25`*, but a NaN in -`theta` is not differentiable — perturbing it yields NaN — so resolve it first, as -`R/gradient.R` does. `Leaf::rd_reference()` is that expression. +`theta` is `g::n_pars` = 16 doubles: the fourteen traits in `set_traits`' argument +order, then `leaf_specific_conductance_max`, then the single-potential path's +`resistance`. `g::par_names()` is that order and every position has a name +(`g::par_vcmax_25`, `g::par_R_d_25`, `g::par_kmax`, ...); `pars` holds positions into +it. ⚠️ R indexes these positions, so reordering the enumeration silently +differentiates the wrong parameter. Three things the free function gives you that a hand-rolled loop would not: diff --git a/vignettes/phylloptim.Rmd b/vignettes/phylloptim.Rmd index fb10151..c2631b6 100644 --- a/vignettes/phylloptim.Rmd +++ b/vignettes/phylloptim.Rmd @@ -342,14 +342,9 @@ Fifteen on the multi-layer path — the fourteen traits from `leaf_traits()`, pl `leaf_specific_conductance_max`, which is not a trait but is fitted like one. The single-potential path adds `resistance`, making sixteen. -⚠️ `R_d_25` comes last rather than in `leaf_traits()`' own order, which puts it -fourteenth. The enumeration appends it because inserting it would have moved -`leaf_specific_conductance_max` and `resistance`, and the C++ side indexes this -list by position. Its value defaults to `NA`, meaning *derive it as -`rd_to_vcmax_ratio_ * vcmax_25`* — and it is differentiable **at that default**, -which is what makes `dY/dvcmax_25` a partial at fixed respiration rather than the -total derivative it used to be. If you want the total, add -`rd_to_vcmax_ratio_ * dY/dR_d_25` back. +`R_d_25`, dark respiration at 25 °C, is one of those fourteen and behaves like any +other trait. So `dY/dvcmax_25` is a **partial** derivative at fixed respiration: a +fit that wants respiration to follow Vcmax moves both and adds the two columns. **Selecting fewer genuinely costs less**: the work is one solve plus two cheap evaluations per parameter, so it scales with what you ask for.