From 61c6b31d317aa955db4fbae587469adbebc20caa Mon Sep 17 00:00:00 2001 From: Andreas Gattringer <andreas.gattringer@univie.ac.at> Date: Sun, 16 Apr 2023 19:36:25 +0200 Subject: [PATCH] made Leslie-matrix consistent with start-of-year conditions + fixed a bug in juvenile survival rate calculation --- src/cats/lambda/leslie_matrix.c | 107 +++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 24 deletions(-) diff --git a/src/cats/lambda/leslie_matrix.c b/src/cats/lambda/leslie_matrix.c index fe5c4ea..eade70b 100644 --- a/src/cats/lambda/leslie_matrix.c +++ b/src/cats/lambda/leslie_matrix.c @@ -60,7 +60,7 @@ get_rate_for_matrix(enum cats_vital_rate_id rate_type, cats_dt_rates rate = calculate_rate(info, N, param, l_param->grid, l_param->row, l_param->col, &override); if (print) { - log_message(LOG_INFO, "%s: %Lf (maximum %Lf) for population %Lf/%Lf", + log_message(LOG_INFO, "%s: %Lf (maximum %Lf) for adult population density %Lf/%Lf", info->name, rate, info->max_rate, N, K); } @@ -68,10 +68,22 @@ get_rate_for_matrix(enum cats_vital_rate_id rate_type, } + + + double * create_leslie_matrix(struct cats_configuration *conf, struct lambda_parameters *l_param, bool silent, int32_t *N_out) { + +#define LM_START +#ifndef LM_START + log_message(LOG_IMPORTANT, "using method LM_MID (old)"); +#else + //log_message(LOG_IMPORTANT, "using method LM_START (new)"); + +#endif + assert (N_out != NULL); const int32_t species_id = l_param->species_id; const int32_t mat_max = get_vital_age_from_param(&conf->param[species_id], VA_AGE_OF_MATURITY_MAX); @@ -108,33 +120,35 @@ create_leslie_matrix(struct cats_configuration *conf, struct lambda_parameters * cats_dt_rates germination_to_adult_survival = get_rate_for_matrix(VR_GERMINATION_TO_ADULT_SURVIVAL, l_param, print_rate); - cats_dt_rates juvenile_survival = get_juvenile_tr_from_germination_to_adult_survival( + cats_dt_rates juvenile_transition_rate = get_juvenile_tr_from_germination_to_adult_survival( germination_to_adult_survival, &conf->param[species_id]); // printf("%Lf %Lf\n", juvenile_survival, germination_to_adult_survival); fflush(stdout); cats_dt_rates hapaxanthy_survival = 1.0; if (l_param->param->hapaxanthy > 0.0) { - hapaxanthy_survival = (1.0 - l_param->param->hapaxanthy); + hapaxanthy_survival = (1.0 - l_param->param->hapaxanthy) * flowering_frequency; assert(hapaxanthy_survival >= 0); assert(hapaxanthy_survival <= 1.0); - log_message(LOG_INFO, "hapaxanthy survival: %Lf", hapaxanthy_survival); + log_message(LOG_INFO, "hapaxanthy survival: %Lf, times flowering frequency %Lf", (1.0 - l_param->param->hapaxanthy), hapaxanthy_survival); } if (print_rate) { - log_message(LOG_INFO, "juvenile transition: %Lf", juvenile_survival); + log_message(LOG_INFO, "juvenile transition: %Lf", juvenile_transition_rate); log_message(LOG_INFO, "local dispersal %Lf", local_dispersal); } - double m0 = (double) age_specific_maturation_rate(0, juvenile_survival, mat_min, mat_max); - double d = (double) (flowering_frequency * seed_yield * local_dispersal); + + + double m0 = (double) age_specific_maturation_rate(0, juvenile_transition_rate, mat_min, mat_max); + double dl = (double) (flowering_frequency * seed_yield * local_dispersal); if (print_rate) { for (int32_t i = 0; i < mat_max + 1; i++) { log_message(LOG_RAW, "m%d = %f\n", i, - (double) age_specific_maturation_rate(i, juvenile_survival, mat_min, mat_max)); + (double) age_specific_maturation_rate(i, juvenile_transition_rate, mat_min, mat_max)); } - log_message(LOG_RAW, "d = %f\n", d); + log_message(LOG_RAW, "d = %f\n", dl); } // special case: @@ -154,34 +168,47 @@ create_leslie_matrix(struct cats_configuration *conf, struct lambda_parameters * //return x; } - // FIRST ROW: transition to seeds1 + // FIRST ROW: transition to seeds0 - // seeds: Si -> S1 + // seeds: Si -> S0 for (int32_t s = 0; s < seed_persistence; s++) { assert(s < N); - matrix[0 * N + s] = (double) (germination_rate * m0 * d * seed_survival); + matrix[0 * N + s] = (double) (seed_survival * germination_rate * m0 * dl); } - // juveniles: Ji -> S1 + // juveniles: Ji -> S0 for (int32_t j = 0; j < mat_max; j++) { + int32_t col = seed_persistence + j; assert(col < N); - cats_dt_rates m = age_specific_maturation_rate(j + 1, juvenile_survival, mat_min, mat_max); - matrix[0 * N + col] = (double) (m * d * seed_survival); + cats_dt_rates m = age_specific_maturation_rate(j + 1, juvenile_transition_rate, mat_min, mat_max); +#ifndef LM_START + matrix[0 * N + col] = (double) (m * dl * seed_survival); + +#else + cats_dt_rates juvenile_survival_rate = age_modified_juvenile_survival_rate( + juvenile_transition_rate, j, mat_min, mat_max); + matrix[0 * N + col] = (double) (juvenile_survival_rate * m * dl); +#endif } - // adults: A -> S1 + // adults: A -> S0 for (int32_t a = seed_persistence + mat_max; a < N; a++) { assert(a == N - 1); - matrix[0 * N + a] = (double) (clonal_growth * d * seed_survival); +#ifndef LM_START + matrix[0 * N + a] = (double) (clonal_growth * dl * seed_survival); +#else + matrix[0 * N + a] = (double) (adult_survival * clonal_growth * dl); +#endif } // SEED ROWS: S_i -> S_{i+1} for (int32_t s = 1; s < seed_persistence; s++) { - matrix[s * N + (s - 1)] = (double) ((1.0 - germination_rate) * seed_survival); + matrix[s * N + (s - 1)] = (double) (seed_survival * (1.0 - germination_rate)); + } - // JUVENILE ROW 1: + // JUVENILE ROW 1: Si -> J0 for (int32_t s = 0; s < seed_persistence; s++) { int32_t row = seed_persistence; if (row * N + s < N * N) { @@ -192,17 +219,31 @@ create_leslie_matrix(struct cats_configuration *conf, struct lambda_parameters * log_message(LOG_RAW, "row = %d\n", row); exit(EXIT_FAILURE); } - matrix[row * N + s] = (double) (germination_rate * (1.0 - m0) * juvenile_survival); +#ifndef LM_START + cats_dt_rates juvenile_survival_rate = age_modified_juvenile_survival_rate( + juvenile_transition_rate, 0, mat_min, mat_max); + matrix[row * N + s] = (double) (germination_rate * (1.0 - m0) * juvenile_survival_rate); +#else + matrix[row * N + s] = (double) ( seed_survival * germination_rate * (1.0 - m0)); +#endif } - // JUVENILE ROWS J2 ...: J_i -> J_{i+1} + // JUVENILE ROWS J1+ ...: J_i -> J_{i+1} for (int32_t j = 0; j < mat_max; j++) { + cats_dt_rates juvenile_survival_rate = age_modified_juvenile_survival_rate( + juvenile_transition_rate, j, mat_min, mat_max); int32_t row = j + seed_persistence + 1; int32_t col = j + seed_persistence; assert(row < N); - cats_dt_rates m = age_specific_maturation_rate(j + 1, juvenile_survival, mat_min, mat_max); - matrix[row * N + col] = (double) ((1.0 - m) * juvenile_survival); + cats_dt_rates m = age_specific_maturation_rate(j + 1, juvenile_transition_rate, mat_min, mat_max); +#ifndef LM_START + + matrix[row * N + col] = (double) ((1.0 - m) * juvenile_survival_rate); +#else + + matrix[row * N + col] = (double) (juvenile_survival_rate * (1.0 - m)); +#endif } @@ -210,18 +251,36 @@ create_leslie_matrix(struct cats_configuration *conf, struct lambda_parameters * int32_t row = seed_persistence + mat_max; assert(row == N - 1); for (int32_t s = 0; s < seed_persistence; s++) { +#ifndef LM_START matrix[row * N + s] = (double) (germination_rate * m0 * adult_survival); +#else + matrix[row * N + s] = (double) (seed_survival *germination_rate * m0 * hapaxanthy_survival); +#endif } for (int32_t j = 0; j < mat_max; j++) { + int32_t col = seed_persistence + j; - cats_dt_rates m = age_specific_maturation_rate(j + 1, juvenile_survival, mat_min, mat_max); + cats_dt_rates m = age_specific_maturation_rate(j + 1, juvenile_transition_rate, mat_min, mat_max); +#ifndef LM_START + assert(col < N - 1); matrix[row * N + col] = (double) (m * adult_survival); +#else + cats_dt_rates juvenile_survival_rate = age_modified_juvenile_survival_rate( + juvenile_transition_rate, j, mat_min, mat_max); + assert(col < N - 1); + matrix[row * N + col] = (double) (juvenile_survival_rate * m * hapaxanthy_survival); +#endif } // LAST ENTRY +#ifndef LM_START matrix[row * N + N - 1] = (double) (clonal_growth * adult_survival * hapaxanthy_survival); +#else + matrix[row * N + N - 1] = (double) (adult_survival * clonal_growth * hapaxanthy_survival); +#endif + return matrix; } -- GitLab