Partition Groups

I am new to C++ and am attempting to apply some simple codes that run well in Matlab to C++. In the case here, I create a vector of n (here 1000) uniform random doubles representing fish lengths ("Cohort"). The cohort is then partitioned into individual that mature at the start ("year 1, spawners1) and the remainder ("Immature1") that remains immature until the following year (if they survive). The Immature1s are then partitioned into survivors that spawn in year 2 ("Spawners2") and the remainder that did not survive ("Morts2").

I have attempted to use vectors for these quantities because the number of Immature1swill be less than n (1000) and so the second "for ..." loop will have to ask for iterations from 1 to the length of Immature1.
I have included the error messages that arise in Visual Studio when I try to build.
I simply do not understand why the two types of erros arise.

I would much appreciate how best to code this simple problem, and to understand why the errors arise.

[code]
//PartitionGroups. Test code

#include <iostream>
#include<vector>
#include <random>
#include <fstream>

using namespace std;

int main()
{
ofstream fout1("C:\\Cpp\\VSProjects\\June4\\Cohort.txt");//initial cohort at first age-at-maturity
ofstream fout2("C:\\Cpp\\VSProjects\\June4\\R1.txt");//unif randoms for probability of maturation
ofstream fout3("C:\\Cpp\\VSProjects\\June4\\R2.txt");// unif randoms for probability of survival of initial cohort immatures
ofstream fout4("C:\\Cpp\\VSProjects\\June4\\Mat1.txt"); //Age1 Matures
ofstream fout5("C:\\Cpp\\VSProjects\\June4\\Immat1.txt");//Age1 Immatures
ofstream fout6("C:\\Cpp\\VSProjects\\June4\\Morts1.txt");//Age 1 immatures that do not survive to age 2.
ofstream fout7("C:Cpp\\VSProjects\\June4\\Age2.txt");//Age2 survivors, both maturing and immatures


int nreps = 1000;
double pMat = 0.4; // maturation rate
double Surv1 = 0.7; // survival rate


std::vector<double> Cohort;
std::vector<double> R1;
std::vector<double> R2;

std::vector<double>Spawners1; //age 1 spawners
std::vector<double> Immature1; // age 1 immatures
std::vector<double> Spawners2; // age 2 spawners
std::vector<double> Morts2; // age 2 morts

random_device rd{};
mt19937 gen(rd());

uniform_real_distribution<double> d1(650.0, 750.0);//initial cohort
uniform_real_distribution<double> d2(0.0, 1.0); //randoms for maturation
uniform_real_distribution<double> d3(0.0, 1.0); //randoms for survival

for (int i = 0; i < nreps; ++i) {
Cohort[i] = d1(gen);

R1[i] = d2(gen);

fout1 << Cohort[i] << endl;
fout2 << R1[i] << endl;


if (R1[i] < pMat)
{
Spawners1[i].push_back(Cohort[i]); //Error Message: "expression must have a class type"
fout4 << Spawners1[i] << endl;
}
else{

Immature1[i].push_back(Cohort[i]); //Error Message: "expression must have a class type"

fout5 << Immature1[i] << endl;
}
}


for (int i = 0; i < Immature1.size(); ++i) {
double R2[i] = d3(gen); //Error Message:"expression must have a constant value"

if (R2[i] < Surv1)
{
// Spawners2[i] = Immature1[i];
Spawners2[i].push_back(Immature1[i]); //Error Message: "expression must have a class type"
}
else
{
// Morts2[i] = Immature1[i];
Morts2[i].push_back(Immature1[i]); //Error Message: "expression must have a class type"
}
fout3 << R2 << endl;
fout6 << Morts2[i] << endl;
fout7 << Spawners2[i] << endl;
}


return 0;
}
Spawners1[i] is not a vector ... it is an element of a vector.

For
Spawners1[i].push_back(Cohort[i])
you presumably meant
Spawners1.push_back(Cohort[i])

Similarly for the other mentioned errors.


It won't work after that because Cohort[i] doesn't exist. You declared Cohort as an empty vector in the line
std::vector<double> Cohort;
and you would have to either declare it with the desired size (probably nreps), or use push_back() to gradually increase it, or use resize() to fix its desired size.


Please:
(1) USE CODE TAGS
(2) Don't put so much code down before you start trying to compile it.
Last edited on
This now works.

The key is to size the <vectors>, either in the constructor as I have done or by using resize(), or even fill(), whatever suits your preference.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//PartitionGroups. Test code

#include <iostream>
#include <vector>
#include <random>
#include <fstream>

using namespace std;

int main()
{
    ofstream fout1("ZZ_Cohort.txt");//initial cohort at first age-at-maturity
    ofstream fout2("ZZ_R1.txt");//unif randoms for probability of maturation
    ofstream fout3("ZZ_R2.txt");// unif randoms for probability of survival of initial cohort immatures
    ofstream fout4("ZZ_Mat1.txt"); //Age1 Matures
    ofstream fout5("ZZ_Immat1.txt");//Age1 Immatures
    ofstream fout6("ZZ_Morts1.txt");//Age 1 immatures that do not survive to age 2.
    ofstream fout7("ZZ_Age2.txt");//Age2 survivors, both maturing and immatures
    
    
    int nreps = 1000;
    double pMat = 0.4; // maturation rate
    double Surv1 = 0.7; // survival rate
    
    std::vector<double> Cohort(nreps);
    std::vector<double> R1(nreps);
    std::vector<double> R2(nreps);
    
    std::vector<double> Spawners1(nreps); //age 1 spawners
    std::vector<double> Immature1(nreps); // age 1 immatures
    std::vector<double> Spawners2(nreps); // age 2 spawners
    std::vector<double> Morts2(nreps); // age 2 morts
    
    random_device rd{};
    mt19937 gen(rd());
    
    uniform_real_distribution<double> d1(650.0, 750.0);//initial cohort
    uniform_real_distribution<double> d2(0.0, 1.0); //randoms for maturation
    uniform_real_distribution<double> d3(0.0, 1.0); //randoms for survival
    
    for (int i = 0; i < nreps; ++i)
    {
        Cohort[i] = d1(gen);
        
        R1[i] = d2(gen);
        
        fout1 << Cohort[i] << endl;
        fout2 << R1[i] << endl;
        
        
        if (R1[i] < pMat)
        {
            Spawners1[i] = Cohort[i];
            fout4 << Spawners1[i] << endl;
        }
        else
        {
            
            Immature1[i] = Cohort[i];
            fout5 << Immature1[i] << endl;
        }
    }
    
    
    for (int i = 0; i < Immature1.size(); ++i)
    {
        R2[i] = d3(gen);
        
        if (R2[i] < Surv1)
        {
            Spawners2[i] = Immature1[i];
        }
        else
        {
            Morts2[i] = Immature1[i];
        }
        
        fout3 << R2[i] << endl;
        fout6 << Morts2[i] << endl;
        fout7 << Spawners2[i] << endl;
    }
    
    
    return 0;
}
Last edited on
Of course, the size of each vector is not always nreps, hence the blanks.

You will have to work out how you handle that aspect. Perhaps push_back a value instead of placing it at a particular indexed location in the <vector>, even use separate indices.

Perhaps <vectors> aren't such a good idea after all, maybe not even needed at all.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/PartitionGroups. Test code

#include <iostream>
#include <vector>
#include <random>
#include <fstream>

using namespace std;

int main()
{
    ofstream f_cohort("ZZ_Cohort.txt");//initial cohort at first age-at-maturity
    ofstream f_r1("ZZ_R1.txt");//prob of maturation
    ofstream f_r2("ZZ_R2.txt");//prob of survival of initial cohort immatures
    ofstream f_age1mature("ZZ_Mat1.txt"); //Age1 Matures
    ofstream f_immat1("ZZ_Immat1.txt");//Age1 Immatures
    ofstream f_morts1("ZZ_Morts1.txt");//Age1 immatures - not survive to age 2.
    ofstream f_age2surv("ZZ_Age2.txt");//Age2 survivors - maturing and immatures
    
    
    int nreps = 1000;
    double pMat = 0.4; // maturation rate
    double Surv1 = 0.7; // survival rate
    
    std::vector<double> Immature1;
    
    random_device rd{};
    mt19937 gen(rd());
    
    uniform_real_distribution<double> d1(650.0, 750.0);//initial cohort
    uniform_real_distribution<double> d2(0.0, 1.0); //randoms for maturation
    uniform_real_distribution<double> d3(0.0, 1.0); //randoms for survival
    
    double Cohort{0};
    double R1{0};
    for (int i = 0; i < nreps; ++i)
    {
        Cohort = d1(gen);
        
        R1 = d2(gen);
        
        f_cohort << Cohort << endl;
        f_r1 << R1 << endl;
        
        
        if (R1 < pMat)
        {
            f_age1mature << Cohort << endl;
        }
        else
        {
            Immature1.push_back(Cohort);
            f_immat1 << Cohort << endl;
        }
    }
    
    double R2{0};
    for (int i = 0; i < Immature1.size(); ++i)
    {
        R2 = d3(gen);
        f_r2 << R2 << endl;
        
        if (R2 < Surv1)
        {
            f_age2surv << Immature1[i] << '\n';
        }
        else
        {
            f_morts1 << Immature1[i] << '\n';
        }
    }
    
    return 0;
}
Last edited on
Thank you all very much. This is very helpful, including the constructive admonishments
Topic archived. No new replies allowed.