155 const int& nyrs_hind,
157 const vector<int>& nsex,
158 const vector<int>& nages,
159 const vector<int>& nlengths,
160 matrix<Type>& lengths,
161 const vector<int>& nlengths_pop,
162 matrix<Type>& lengths_pop,
163 const vector<int>& flt_spp,
164 const vector<int>& flt_sel_type,
165 const vector<int>& flt_varying_sel,
166 const vector<int>& flt_sel_dim,
167 const vector<int>& bin_first_selected,
168 const vector<int>& flt_n_sel_bins,
169 const vector<int>& flt_sel_cap_bin,
170 const vector<int>& sel_norm_bin1,
171 const vector<int>& sel_norm_bin2,
172 const vector<int>& sel_norm_scope,
173 const vector<int>& flt_sel_start_yr,
174 matrix<Type>& emp_sel_obs,
175 matrix<int>& emp_sel_ctl,
176 array<Type>& log_sel_slp,
177 array<Type>& log_sel_slp_dev,
178 array<Type>& sel_inf,
179 array<Type>& sel_inf_dev,
180 array<Type>& sel_coff,
181 array<Type>& sel_coff_dev,
182 array<Type> &avg_sel,
183 array<Type> &non_par_sel,
184 array<Type> &log_non_par_sel,
185 array<Type> &sel_at_length,
186 array<Type> &sel_at_age,
187 array<Type>& growth_matrix,
189 array<Type>& sel_slp_off, array<Type>& sel_slp_off_nat,
190 array<Type>& sel_inf_off, array<Type>& sel_inf_off_nat,
191 array<Type>& sel_coff_off, array<Type>& sel_coff_off_nat,
192 const int& sel_apical_on,
193 array<Type>& log_sel_apical,
194 array<Type>& sel_apical_off, array<Type>& sel_apical_off_nat,
195 array<Type>& sel_dn6,
196 array<Type>& sel_dn6_off, array<Type>& sel_dn6_off_nat,
197 matrix<int>& sel_dn6_ends
199 sel_at_age.setZero();
200 sel_at_length.setZero();
203 for (
int i = 0; i < emp_sel_obs.rows(); i++) {
204 int flt = emp_sel_ctl(i, 0) - 1;
205 int sp = emp_sel_ctl(i, 1) - 1;
206 int sex_in = emp_sel_ctl(i, 2);
207 int yr = emp_sel_ctl(i, 3) - styr;
208 if (flt_sel_type(flt) != 0 || yr >= nyrs_hind)
continue;
210 int sex_first = (sex_in == 0) ? 0 : sex_in - 1;
211 int sex_last = (sex_in == 0 && nsex(sp) == 2) ? 1 : sex_first;
212 for (
int sex = sex_first; sex <= sex_last; sex++) {
213 for (
int age = 0; age < nages(sp); age++) {
214 if (!
isNA(emp_sel_obs(i, age))) sel_at_age(flt, sex, age, yr) = emp_sel_obs(i, age);
220 for (
int flt = 0; flt < n_flt; flt++) {
221 int sp = flt_spp(flt);
222 int sel_type = flt_sel_type(flt);
223 if (sel_type == 0)
continue;
227 const int SEL_CASE_NP_INTEGRABLE_WALK = -13;
228 int sel_case = (sel_type == 13 && flt_varying_sel(flt) == 4)
229 ? SEL_CASE_NP_INTEGRABLE_WALK : sel_type;
233 bool is_length_based = flt_sel_dim(flt) == 1;
234 array<Type>& sel = is_length_based ? sel_at_length : sel_at_age;
235 int nbins = is_length_based ? nlengths_pop(sp) : nages(sp);
236 int n_sel_bins = flt_n_sel_bins(flt);
240 vector<Type> x(nbins);
241 for (
int b = 0; b < nbins; b++) {
242 if (!is_length_based) {
244 }
else if (nbins < 2) {
245 x(b) = lengths_pop(sp, b);
247 Type w = (b + 1 < nbins) ? (lengths_pop(sp, b + 1) - lengths_pop(sp, b))
248 : (lengths_pop(sp, b) - lengths_pop(sp, b - 1));
249 x(b) = lengths_pop(sp, b) + 0.5 * w;
254 Type binwidth = (is_length_based && nbins > 1)
255 ? (lengths_pop(sp, nbins / 2) - lengths_pop(sp, nbins / 2 - 1)) : Type(1.0);
258 array<Type> log_walk(nsex(sp), nbins, nyrs_hind); log_walk.setZero();
260 for (
int yr = 0; yr < nyrs_hind; yr++) {
261 for (
int sex = 0; sex < nsex(sp); sex++) {
265 auto slope = [&](
int k) -> Type {
266 return exp(log_sel_slp(k, flt, sex) + log_sel_slp_dev(k, flt, sex, yr)
267 + sel_slp_off(k, flt, sex, yr)) + sel_slp_off_nat(k, flt, sex, yr);
269 auto inflection = [&](
int k) -> Type {
270 return (sel_inf(k, flt, sex) + sel_inf_dev(k, flt, sex, yr)
271 + sel_inf_off_nat(k, flt, sex, yr)) * exp(sel_inf_off(k, flt, sex, yr));
278 Type inf = inflection(0);
279 for (
int bin = 0; bin < nbins; bin++) {
280 sel(flt, sex, bin, yr) = invlogit(slp * (x(bin) - inf));
287 case SEL_CASE_NP_INTEGRABLE_WALK: {
290 vector<Type> coef(n_sel_bins);
291 for (
int bin = 0; bin < n_sel_bins; bin++) {
292 if (sel_case == SEL_CASE_NP_INTEGRABLE_WALK) {
293 Type inc = (yr > flt_sel_start_yr(flt)) ? sel_coff_dev(flt, sex, bin, yr) : Type(0.0);
294 log_walk(sex, bin, yr) = (yr > 0 ? log_walk(sex, bin, yr - 1) : Type(0.0)) + inc;
295 coef(bin) = sel_coff(flt, sex, bin) + log_walk(sex, bin, yr);
297 coef(bin) = sel_coff(flt, sex, bin) + sel_coff_dev(flt, sex, bin, yr);
305 vector<Type> log_curve(nbins);
306 for (
int bin = 0; bin < nbins; bin++) {
307 int b = (bin < n_sel_bins) ? bin : (n_sel_bins - 1);
308 log_curve(bin) = coef(b);
311 for (
int bin = 0; bin < nbins; bin++) {
312 log_non_par_sel(flt, sex, bin, yr) = log_curve(bin) - centre;
313 non_par_sel(flt, sex, bin, yr) = exp(log_non_par_sel(flt, sex, bin, yr));
314 sel(flt, sex, bin, yr) = non_par_sel(flt, sex, bin, yr);
322 Type slp1 = slope(0);
323 Type inf1 = inflection(0);
324 Type slp2 = slope(1);
325 Type inf2 = inflection(1);
326 for (
int bin = 0; bin < nbins; bin++) {
327 sel(flt, sex, bin, yr) = invlogit(slp1 * (x(bin) - inf1)) * invlogit(-slp2 * (x(bin) - inf2));
333 Type slp2 = slope(1);
334 Type inf2 = inflection(1);
335 for (
int bin = 0; bin < nbins; bin++) {
336 sel(flt, sex, bin, yr) = invlogit(-slp2 * (x(bin) - inf2));
343 for (
int bin = bin_first_selected(flt); bin < nbins; bin++) {
344 if (bin < n_sel_bins) cum_sum += sel_coff(flt, sex, bin) + sel_coff_dev(flt, sex, bin, yr);
345 sel(flt, sex, bin, yr) = cum_sum;
348 Type log_ref = -1e10;
349 if (sel_norm_bin1(flt) >= 0 && sel_norm_bin2(flt) < 0) {
350 log_ref = sel(flt, sex, sel_norm_bin1(flt), yr);
352 for (
int bin = 0; bin < nbins; bin++) log_ref =
max2(log_ref, sel(flt, sex, bin, yr));
354 for (
int bin = 0; bin < nbins; bin++) {
355 sel(flt, sex, bin, yr) = exp(sel(flt, sex, bin, yr) - log_ref);
362 for (
int bin = 0; bin < nbins; bin++) {
363 int b = (bin < n_sel_bins) ? bin : (n_sel_bins - 1);
364 sel(flt, sex, bin, yr) = invlogit(sel_coff(flt, sex, b) + sel_coff_dev(flt, sex, b, yr));
371 Type peak = inflection(0);
372 Type sigma_asc = slope(0);
373 Type sigma_desc = slope(1);
374 Type right_floor = invlogit(inflection(1));
375 for (
int bin = 0; bin < nbins; bin++) {
376 Type d = x(bin) - peak;
377 Type w = invlogit(20.0 * d);
378 Type asc_gauss = exp(-0.5 * pow(d / sigma_asc, 2.0));
379 Type desc_gauss = exp(-0.5 * pow(d / sigma_desc, 2.0));
380 sel(flt, sex, bin, yr) = (1.0 - w) * asc_gauss
381 + w * (right_floor + (1.0 - right_floor) * desc_gauss);
389 bool from_base = (yr <= flt_sel_start_yr(flt));
390 for (
int bin = 0; bin < nbins; bin++) {
391 if (bin < n_sel_bins) {
392 Type prev = from_base ? sel_coff(flt, sex, bin) : log_walk(sex, bin, yr - 1);
393 log_walk(sex, bin, yr) = prev + sel_coff_dev(flt, sex, bin, yr);
395 log_walk(sex, bin, yr) = log_walk(sex, n_sel_bins - 1, yr);
399 for (
int bin = 0; bin < bin_first_selected(flt); bin++) log_walk(sex, bin, yr) = 0.0;
401 vector<Type> walk(nbins);
402 for (
int bin = 0; bin < nbins; bin++) walk(bin) = log_walk(sex, bin, yr);
404 for (
int bin = 0; bin < nbins; bin++) log_walk(sex, bin, yr) -= centre;
407 int cap = flt_sel_cap_bin(flt);
408 vector<Type> capped(nbins);
409 for (
int bin = 0; bin < nbins; bin++) {
410 capped(bin) = (cap >= 0 && bin > cap) ? log_walk(sex, cap, yr) : log_walk(sex, bin, yr);
413 for (
int bin = 0; bin < nbins; bin++) {
414 log_non_par_sel(flt, sex, bin, yr) = capped(bin) - recentre;
415 non_par_sel(flt, sex, bin, yr) = exp(log_non_par_sel(flt, sex, bin, yr));
416 sel(flt, sex, bin, yr) = non_par_sel(flt, sex, bin, yr);
425 Type inf = (sel_inf(0, flt, sex) + sel_inf_off_nat(0, flt, sex, yr))
426 * exp(sel_inf_dev(0, flt, sex, yr) + sel_inf_off(0, flt, sex, yr));
427 for (
int bin = 0; bin < nbins; bin++) {
428 Type x_val = is_length_based ? x(bin) : Type(bin + 1.5);
429 sel(flt, sex, bin, yr) = invlogit(slp * (x_val - inf));
432 Type log_s1 = (sel_inf(1, flt, sex) + sel_inf_off_nat(1, flt, sex, yr))
433 * exp(sel_inf_dev(1, flt, sex, yr) + sel_inf_off(1, flt, sex, yr));
434 sel(flt, sex, 0, yr) = exp(log_s1);
443 for (
int k = 0; k < 6; k++) {
444 P(k) = (sel_dn6(k, flt, sex) + sel_dn6_off_nat(k, flt, sex, yr)) * exp(sel_dn6_off(k, flt, sex, yr));
447 Type upselex = exp(P(2));
448 Type downselex = exp(P(3));
452 if (is_length_based) {
453 while (startbin < nbins - 1 && lengths_pop(sp, startbin) < lengths(sp, 0)) startbin++;
455 Type x_first = x(startbin);
456 Type x_last = x(nbins - 1);
457 Type peak2 = peak + binwidth + (0.99 * x_last - peak - binwidth) / (1.0 + exp(-P(1)));
458 Type point1 = invlogit(P(4));
459 Type point2 = invlogit(P(5));
460 Type t1min = exp(-
square(x_first - peak) / upselex);
461 Type t2min = exp(-
square(x_last - peak2) / downselex);
462 for (
int bin = startbin; bin < nbins; bin++) {
463 Type t1 = x(bin) - peak;
464 Type t2 = x(bin) - peak2;
465 Type join1 = invlogit(20.0 * t1 / (1.0 + CppAD::abs(t1)));
466 Type join2 = invlogit(20.0 * t2 / (1.0 + CppAD::abs(t2)));
467 Type asc = (sel_dn6_ends(flt, 0) == 1)
468 ? point1 + (1.0 - point1) * (exp(-
square(t1) / upselex) - t1min) / (1.0 - t1min)
469 : exp(-
square(t1) / upselex);
470 Type dsc = (sel_dn6_ends(flt, 1) == 1)
471 ? 1.0 + (point2 - 1.0) * (exp(-
square(t2) / downselex) - 1.0) / (t2min - 1.0)
472 : exp(-
square(t2) / downselex);
473 sel(flt, sex, bin, yr) = asc * (1.0 - join1) + join1 * ((1.0 - join2) + dsc * join2);
476 if (is_length_based && startbin > 0) {
477 Type sel_start = sel(flt, sex, startbin, yr);
478 for (
int bin = 0; bin < startbin; bin++) {
479 sel(flt, sex, bin, yr) =
square(x(bin) / x(startbin)) * sel_start;
492 if (sel_apical_on == 1) {
493 for (
int yr = 0; yr < nyrs_hind; yr++) {
494 for (
int sex = 0; sex < nsex(sp); sex++) {
495 Type scale = exp(log_sel_apical(flt, sex) + sel_apical_off(flt, sex, yr))
496 + sel_apical_off_nat(flt, sex, yr);
497 for (
int bin = 0; bin < nbins; bin++) sel(flt, sex, bin, yr) *= scale;
504 flt, nyrs_hind, nyrs, flt_spp, flt_sel_type, flt_sel_dim, bin_first_selected, nages,
505 nlengths_pop, nsex, sel_norm_bin1, sel_norm_bin2, sel_norm_scope, sel);
508 if (is_length_based) {
509 int wtind = nspp * 2 + flt;
510 for (
int yr = 0; yr < nyrs; yr++) {
511 for (
int sex = 0; sex < nsex(sp); sex++) {
513 sel_at_length, growth_matrix, sel_at_age);