Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 39 additions & 4 deletions SS_expval.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ FUNCTION void Get_expected_values(const int y, const int t);
{
case (1): // units are biomass, so accumulate body weight into the bins; Assume that bin demarcations are also in biomass
{
if (SzFreq_Omit_Small(SzFreqMethod) == 1)
if (SzFreq_Omit_Small(SzFreqMethod) == 1)
{
while (wt_len_low(s, 1, z1 + 1) < SzFreq_bins(SzFreqMethod, 1) && z1 < z2)
{
Expand Down Expand Up @@ -776,6 +776,7 @@ FUNCTION void Get_expected_values(const int y, const int t);
{
if (SzFreq_scale(SzFreqMethod) <= 2) // bin demarcations are in weight units (1=kg, 2=lbs), so uses wt_len to compare to bins
{
warning<<"process_szfreq"<<endl;
if (SzFreq_Omit_Small(SzFreqMethod) == 1)
{
while (wt_len_low(s, 1, z1 + 1) < SzFreq_bins(SzFreqMethod, 1) && z1 < z2)
Expand All @@ -796,8 +797,10 @@ FUNCTION void Get_expected_values(const int y, const int t);

for (z = z1; z <= z2; z++)
{
warning<<z <<" size " << wt_len_low(s, 1, z)<<" bin "<<ibin<< " size_at_bin "<<SzFreq_bins2(SzFreqMethod, ibin)<<" save_ibin " <<ibinsave<<" botbin "<<botbin<<" topbin "<<topbin<< endl;
if (ibin == SzFreq_Nbins(SzFreqMethod))
{
warning<<" last bin "<<ibin<<endl;
SzFreqTrans(SzFreqMethod_seas, z, ibinsave) = 1.;
} //checkup<<" got to last ibin, so put rest of popbins here"<<endl;
else
Expand All @@ -806,25 +809,40 @@ FUNCTION void Get_expected_values(const int y, const int t);
{
ibin++;
ibinsave++;
} //checkup<<" incr ibin "<<z<<" "<<ibin<<" "<<len_bins(z)<<" "<<len_bins_dat(ibin);
warning<<" wt>=topbin, so incr ibin "<<ibin<<" ibinsave "<<ibinsave<<endl;
}
if (ibin > 1)
{
botbin = SzFreq_bins2(SzFreqMethod, ibin);
warning<<" incr botbin to "<<botbin<<endl;

}
if (ibin == SzFreq_Nbins(SzFreqMethod)) // checkup<<" got to last ibin, so put rest of popbins here"<<endl;
if (ibin == SzFreq_Nbins(SzFreqMethod))
{
warning<<" got to last ibin, so put rest of popbins here"<<endl;

SzFreqTrans(SzFreqMethod_seas, z, ibinsave) = 1.;
topbin = 99999.;
}
else
{
topbin = SzFreq_bins2(SzFreqMethod, ibin + 1);
warning<<"check using topbin = "<<topbin<<endl;
if (wt_len_low(s, 1, z) >= botbin && wt_len_low(s, 1, z + 1) <= topbin) //checkup<<" pop inside dat, put here"<<endl;
{
warning<<"all in bin"<<endl;
SzFreqTrans(SzFreqMethod_seas, z, ibinsave) = 1.;
}
else // checkup<<" overlap"<<endl;
else if (wt_len_low(s, 1, z) >= topbin)
{
// this should have the fish in z size range distributed across all bins >= size(z) until get to overlap
warning<<" size > current bin, increment bin index "<<endl;
ibin++;
ibinsave++;
}
else
{
warning<<" overlap"<<endl;
SzFreqTrans(SzFreqMethod_seas, z, ibinsave + 1) = (wt_len_low(s, 1, z + 1) - topbin) / wt_len_fd(s, 1, z);
SzFreqTrans(SzFreqMethod_seas, z, ibinsave) = 1. - SzFreqTrans(SzFreqMethod_seas, z, ibinsave + 1);
}
Expand All @@ -835,6 +853,23 @@ FUNCTION void Get_expected_values(const int y, const int t);

else // bin demarcations are in length unit (3=cm, 4=inch) so uses population len_bins to compare to data bins
{
/* wt_len_low(s, 1, z1 + 1) < SzFreq_bins(SzFreqMethod, 1) && z1 < z2)
FUNCTION dvector rebin(const dvector& src_edges, const dvector& src_counts, const dvector& dest_edges)
3darray wt_len_low(1,nseas,1,N_GP,1,nlength2) // wt at lower edge of size bin
*/
dvector freq_in(1, z2-z1); // fill the input
freq_in = 1.;
echoinput << " z1: " << z1 << " z2: " << z2 << endl;
echoinput << " freq_in: " << freq_in << endl;
dvector bins_in(1, z2-z1);
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vector size and assignment mismatch. bins_in needs z2-z1+2 elements to store bin edges (boundaries) for z2-z1+1 bins. The vector should be sized dvector bins_in(1, z2-z1+2) to accommodate N+1 edges for N bins

Suggested change
dvector bins_in(1, z2-z1);
dvector bins_in(1, z2-z1+2);

Copilot uses AI. Check for mistakes.
bins_in = len_bins2(z1, z2); // input bins shifted
Comment on lines +860 to +865
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Vector size mismatch. A vector from index 1 to z2-z1 has size z2-z1, but should have size z2-z1+1 to match the number of bins from z1 to z2 inclusive. Should be dvector freq_in(1, z2-z1+1)

Suggested change
dvector freq_in(1, z2-z1); // fill the input
freq_in = 1.;
echoinput << " z1: " << z1 << " z2: " << z2 << endl;
echoinput << " freq_in: " << freq_in << endl;
dvector bins_in(1, z2-z1);
bins_in = len_bins2(z1, z2); // input bins shifted
dvector freq_in(1, z2-z1+1); // fill the input (one element per bin edge from z1 to z2 inclusive)
freq_in = 1.;
echoinput << " z1: " << z1 << " z2: " << z2 << endl;
echoinput << " freq_in: " << freq_in << endl;
dvector bins_in(1, z2-z1+1);
bins_in = len_bins2(z1, z2); // input bins shifted (edges from z1 to z2 inclusive)

Copilot uses AI. Check for mistakes.
echoinput << " bins_in: " << bins_in << endl;
// dvector bins_out(1, z2-z1) = SzFreq_bins(SzFreqMethod
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incomplete commented-out code should be removed. This appears to be leftover development code that creates confusion.

Suggested change
// dvector bins_out(1, z2-z1) = SzFreq_bins(SzFreqMethod

Copilot uses AI. Check for mistakes.
dvector freq_out(1, SzFreq_Nbins(SzFreqMethod));

freq_out = rebin(bins_in, freq_in, SzFreq_bins(SzFreqMethod));
echoinput << " freq_out: " << freq_out << endl;

if (SzFreq_Omit_Small(SzFreqMethod) == 1)
{
while (len_bins2(z1 + 1) < SzFreq_bins(SzFreqMethod, 1))
Expand Down
38 changes: 38 additions & 0 deletions SS_miscfxn.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,41 @@ FUNCTION dvariable Comp_logL_Dirichlet(const double& Nsamp, const dvariable& dir
logL = sum(gammln(Nsamp * obs_comp + dirichlet_Parm * exp_comp)) - sum(gammln(dirichlet_Parm * exp_comp));
return (logL);
}

FUNCTION dvector rebin(const dvector& src_edges, const dvector& src_counts, const dvector& dest_edges)
{
/*
This implementation takes two vectors representing the boundaries (edges) of the source
and destination bins, and one vector for the source counts.

Rebins frequency data from one set of boundaries to another.
@param src_edges Boundaries of the original bins (size N+1).
@param src_counts Frequency/counts in original bins (size N).
@param dest_edges Boundaries of the new bins (size M+1).
@return Vector of rebinned frequency data (size M).
*/

dvector dest_counts(dest_edges.size() - 1, 0.0);
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incorrect constructor syntax for dvector initialization. ADMB dvectors use index ranges, not size-based construction. Should be dvector dest_counts(1, dest_edges.size() - 1); dest_counts.initialize();

Suggested change
dvector dest_counts(dest_edges.size() - 1, 0.0);
dvector dest_counts(1, dest_edges.size() - 1);
dest_counts.initialize();

Copilot uses AI. Check for mistakes.
for (int i = 0; i < dest_counts.size(); ++i) {
double d_low = dest_edges[i];
double d_high = dest_edges[i + 1];

for (int j = 0; j < src_counts.size(); ++j) {
double s_low = src_edges[j];
double s_high = src_edges[j + 1];

// Calculate the overlap between [d_low, d_high] and [s_low, s_high]
double overlap_low = max(d_low, s_low);
double overlap_high = min(d_high, s_high);

if (overlap_low < overlap_high) {
double overlap_width = overlap_high - overlap_low;
double src_bin_width = s_high - s_low;

// Distribute source count proportionally to the overlap area
dest_counts[i] += src_counts[j] * (overlap_width / src_bin_width);
}
}
}
Comment on lines +137 to +158
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ADMB dvector indexing is 1-based by default, not 0-based. This loop should iterate from the vector's indexmin() to indexmax(), or adjust the initialization to use 0-based indexing with dvector dest_counts(0, dest_edges.size() - 2)

Suggested change
dvector dest_counts(dest_edges.size() - 1, 0.0);
for (int i = 0; i < dest_counts.size(); ++i) {
double d_low = dest_edges[i];
double d_high = dest_edges[i + 1];
for (int j = 0; j < src_counts.size(); ++j) {
double s_low = src_edges[j];
double s_high = src_edges[j + 1];
// Calculate the overlap between [d_low, d_high] and [s_low, s_high]
double overlap_low = max(d_low, s_low);
double overlap_high = min(d_high, s_high);
if (overlap_low < overlap_high) {
double overlap_width = overlap_high - overlap_low;
double src_bin_width = s_high - s_low;
// Distribute source count proportionally to the overlap area
dest_counts[i] += src_counts[j] * (overlap_width / src_bin_width);
}
}
}
// dest_counts has one fewer element than dest_edges and follows the same index base.
dvector dest_counts(dest_edges.indexmin(), dest_edges.indexmax() - 1);
dest_counts.initialize();
for (int i = dest_counts.indexmin(); i <= dest_counts.indexmax(); ++i)
{
double d_low = dest_edges(i);
double d_high = dest_edges(i + 1);
for (int j = src_counts.indexmin(); j <= src_counts.indexmax(); ++j)
{
double s_low = src_edges(j);
double s_high = src_edges(j + 1);
// Calculate the overlap between [d_low, d_high] and [s_low, s_high]
double overlap_low = max(d_low, s_low);
double overlap_high = min(d_high, s_high);
if (overlap_low < overlap_high)
{
double overlap_width = overlap_high - overlap_low;
double src_bin_width = s_high - s_low;
// Distribute source count proportionally to the overlap area
dest_counts(i) += src_counts(j) * (overlap_width / src_bin_width);
}
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +137 to +158
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same indexing issue as outer loop. ADMB vectors use 1-based indexing by default. Should iterate from src_counts.indexmin() to src_counts.indexmax()

Suggested change
dvector dest_counts(dest_edges.size() - 1, 0.0);
for (int i = 0; i < dest_counts.size(); ++i) {
double d_low = dest_edges[i];
double d_high = dest_edges[i + 1];
for (int j = 0; j < src_counts.size(); ++j) {
double s_low = src_edges[j];
double s_high = src_edges[j + 1];
// Calculate the overlap between [d_low, d_high] and [s_low, s_high]
double overlap_low = max(d_low, s_low);
double overlap_high = min(d_high, s_high);
if (overlap_low < overlap_high) {
double overlap_width = overlap_high - overlap_low;
double src_bin_width = s_high - s_low;
// Distribute source count proportionally to the overlap area
dest_counts[i] += src_counts[j] * (overlap_width / src_bin_width);
}
}
}
// ADMB vectors are 1-based by default; derive index ranges from the edge vectors.
int dest_min = dest_edges.indexmin();
int dest_max = dest_edges.indexmax() - 1; // last bin uses dest_edges(dest_max+1)
dvector dest_counts(dest_min, dest_max);
dest_counts.initialize();
for (int i = dest_min; i <= dest_max; ++i)
{
double d_low = dest_edges(i);
double d_high = dest_edges(i + 1);
int src_min = src_counts.indexmin();
int src_max = src_counts.indexmax();
for (int j = src_min; j <= src_max; ++j)
{
double s_low = src_edges(j);
double s_high = src_edges(j + 1);
// Calculate the overlap between [d_low, d_high] and [s_low, s_high]
double overlap_low = max(d_low, s_low);
double overlap_high = min(d_high, s_high);
if (overlap_low < overlap_high)
{
double overlap_width = overlap_high - overlap_low;
double src_bin_width = s_high - s_low;
// Distribute source count proportionally to the overlap area
dest_counts(i) += src_counts(j) * (overlap_width / src_bin_width);
}
}
}

Copilot uses AI. Check for mistakes.
return (dest_counts);
}
Loading