Exemplo n.º 1
0
// this one sets up dx*dy majority vote problems without diffusion
MajorityVoteProblem::MajorityVoteProblem(Real length, int dx, int dy, uint numMolecules, uint nReds, uint numEncounters, Real reactionProb, Real recognitionError, const std::string &initScriptsPath)
    : DiffusionModel(length, dx, dy), m_individual(false), m_isNonDiffusive(true)
{
    if (numEncounters < 3) {
        std::cout <<"ERROR: Need at least three encounters!\n";
        exit(1);
    }

    // this list will hold all red and green species
    // we need (i^2+i)/2 species per red and green
    // where i is the number of encounters after which the species "votes"
    uint maxSpecies = (numEncounters*numEncounters+numEncounters)/2;
    std::vector<gpgmp::Species *> speciesListRed(maxSpecies);
    std::vector<gpgmp::Species *> speciesListGreen(maxSpecies);

    // add species and reactions corresponding to scheme:
    // Rxy - red, has encountered x red and y green robots
    // Gxy - green, has encountered x red and y green robots
    uint c=0;
    for (uint i=0; i<numEncounters; i++) {
        for (uint j=0; j<numEncounters-i; j++) {
            // add species
            std::ostringstream snamered;
            snamered << "R"<<i<<j;
            speciesListRed[c] = addSpecies(snamered.str(), 0.);
            std::ostringstream snamegreen;
            snamegreen << "G"<<i<<j;
            speciesListGreen[c] = addSpecies(snamegreen.str(),0.);

            // print out
            std::cout <<"Added species "<<snamered.str()<<" and "<<snamegreen.str()<<".\n";
            // increase counter;
            c++;
        }
    } // create species

    // set diffusivity and drift for species
    setParameter("diffX", 0.);
    setParameter("diffY", 0.);
    setParameter("driftX", 0.);
    setParameter("driftY", 0.);

    // set homogeneous diffusivity and drift
    setComputeDriftDiffusivityMethod(gpgmp::DT_HOMOGENEOUS);

    // these are the actual reaction probabilities for the correct reaction and the error reaction
    double kcorrect = reactionProb*(1.-2.*recognitionError-recognitionError*recognitionError);
    double kwrong1  = reactionProb*recognitionError;
    double kwrongb  = reactionProb*recognitionError*recognitionError;

    // add reactions
    // Gxy+Rwz -> Gx+1y + Rwz+1
    // Gxy+Rwz -> Gxy+1 + Rw+1z (for recognition error)
    uint cg = 0;
    uint totnreacts=0.; // just debug counter to count number of reactions
    for (uint x=0; x<numEncounters; x++) {
        for (uint y=0; y<numEncounters-x; y++) {
            // to name the reaction
            std::ostringstream snamers;
            std::ostringstream snamerd;
            std::ostringstream snamerdw;

            // find source and target species for green
            Species *Gxy = speciesListGreen[cg];
            snamers << "G"<<x<<y<<"("<<Gxy->id()<<")";

            Species *Txp1y;
            Species *Txyp1;
            if ((x+y)==(numEncounters-1)) {
                // target species is either G00 or R00
                if (x>=y) {
                    // turns red
                    Txp1y = speciesListRed[0];
                    snamerd <<"R00"<<"("<<Txp1y->id()<<")";

                    // wrong decision
                    if (x>y) {
                        Txyp1 = speciesListRed[0];
                        snamerdw <<"R00"<<"("<<Txyp1->id()<<")";
                    }
                    else {
                        Txyp1 = speciesListGreen[0];
                        snamerdw <<"G00"<<"("<<Txyp1->id()<<")";
                    }
                } else {
                    // stays green
                    Txp1y = speciesListGreen[0];
                    snamerd <<"G00"<<"("<<Txp1y->id()<<")";
                    // and the wrong decision stays green too
                    Txyp1 = speciesListGreen[0];
                    snamerdw <<"G00"<<"("<<Txyp1->id()<<")";
                }
            } else {
                // target species is Gx+1y
                Txp1y = speciesListGreen[cg+(numEncounters-x)];
                snamerd <<"G"<<x+1<<y<<"("<<Txp1y->id()<<")";
                // or Gxy+1
                Txyp1 = speciesListGreen[cg+1];
                snamerdw <<"G"<<x<<y+1<<"("<<Txyp1->id()<<")";
            }

            // now pair with all red robots
            uint cr=0;
            for (uint w=0; w<numEncounters; w++) {
                for (uint z=0; z<numEncounters-w; z++) {
                    // find source and target species for red
                    Species *Rxy = speciesListRed[cr];
                    std::ostringstream sss;
                    std::ostringstream ssd;
                    std::ostringstream ssdw;
                    sss << "R"<<w<<z << "("<<Rxy->id()<<")";

                    Species *Twzp1;
                    Species *Twp1z;
                    if ((w+z)==(numEncounters-1)) {
                        // target species is either G00 or R00
                        if (w>z) {
                            // stays red
                            Twzp1 = speciesListRed[0];
                            ssd <<"R00" << "("<<Twzp1->id()<<")";
                            // and the wrong decision .. stays red too
                            Twp1z = speciesListRed[0];
                            ssdw <<"R00" << "("<<Twp1z->id()<<")";
                        } else {
                            // stays green
                            Twzp1 = speciesListGreen[0];
                            ssd <<"G00" << "("<<Twzp1->id()<<")";
                            if (w==z) {
                                Twp1z = speciesListRed[0];
                                ssdw <<"R00" << "("<<Twp1z->id()<<")";
                            } else {
                                Twp1z = speciesListGreen[0];
                                ssdw <<"G00" << "("<<Twp1z->id()<<")";
                            }
                        }
                    } else {
                        // target species is Rw+1z
                        Twzp1 = speciesListRed[cr+1];
                        ssd <<"R"<<w<<z+1<< "("<<Twzp1->id()<<")";
                        // and Rwzp1
                        Twp1z = speciesListRed[cr+(numEncounters-w)];
                        ssdw <<"R"<<w+1<<z<< "("<<Twp1z->id()<<")";
                    }

                    std::ostringstream rname, rnamew;
                    rname <<snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str()<<" + " << ssd.str();
                    std::cout <<"Adding reaction "<<rname.str()<<".\n";
                    totnreacts++;
                    Reaction *r = addReaction (rname.str(), kcorrect, Gxy, Rxy);
                    r->setProductStoichiometry(Txp1y, 1);
                    if (Txp1y == Twzp1)
                        r->setProductStoichiometry(Twzp1, 2);
                    else
                        r->setProductStoichiometry(Twzp1, 1);

                    // and add wrong reaction if needed
                    if (recognitionError > 0) {
                        // both wrong
                        rnamew <<snamers.str()<<" + "<<sss.str()<<" -> "<<snamerdw.str()<<" + " << ssdw.str();
                        std::cout <<"Adding errenous reaction "<<rnamew.str()<<".\n"<<std::flush;
                        totnreacts++;
                        r = addReaction(rnamew.str(), kwrongb, Gxy, Rxy);
                        r->setProductStoichiometry(Txyp1, 1);
                        if (Txyp1 == Twp1z)
                            r->setProductStoichiometry(Twp1z, 2);
                        else
                            r->setProductStoichiometry(Twp1z, 1);

                        std::ostringstream rnamew1, rnamew2;
                        // first wrong
                        rnamew1 <<snamers.str()<<" + "<<sss.str()<<" -> "<<snamerdw.str()<<" + " << ssd.str();
                        std::cout <<"Adding errenous reaction (first wrong) "<<rnamew1.str()<<".\n"<<std::flush;
                        totnreacts++;
                        r = addReaction(rnamew.str(), kwrong1, Gxy, Rxy);
                        r->setProductStoichiometry(Txyp1, 1);
                        if (Txyp1 == Twzp1)
                            r->setProductStoichiometry(Twzp1, 2);
                        else
                            r->setProductStoichiometry(Twzp1, 1);

                        // second wrong
                        rnamew2 <<snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str()<<" + " << ssdw.str();
                        std::cout <<"Adding errenous reaction (second wrong) "<<rnamew2.str()<<".\n"<<std::flush;
                        totnreacts++;
                        r = addReaction(rnamew2.str(), kwrong1, Gxy, Rxy);
                        r->setProductStoichiometry(Txp1y, 1);
                        if (Txp1y == Twp1z)
                            r->setProductStoichiometry(Twp1z, 2);
                        else
                            r->setProductStoichiometry(Twp1z, 1);
                    }
                    // increase counter
                    cr++;
                } // pair with red robots z
            } // pair with red robots w

            // increase counter
            cg++;
        } // green robots y
    } // green robots x

    // Gxy+Gwz -> Gxy+1 + Gwz+1
    for (uint x=0; x<maxSpecies; x++) {
        for (uint y=x; y<maxSpecies; y++) {
            // get source species
            Species *G1 = speciesListGreen[x];
            Species *G2 = speciesListGreen[y];

            // get target species 1
            Species *T1;
            Species *T1wrong;

            // is it at marginal position?
            if (isMarginal(x, numEncounters)) {
                // check if over changeover limit (see notebook index_computations.nb)
                if (x > getChangeoverLimit(x, numEncounters)) {
                    // change to red
                    T1 = speciesListRed[0];
                    T1wrong = speciesListRed[0];
                } else {
                    T1 = speciesListGreen[0];

                    // wrong species
                    if (x==getChangeoverLimit(x, numEncounters))
                        T1wrong = speciesListRed[0];
                    else
                        T1wrong = speciesListGreen[0];
                }
            } else {
                T1 = speciesListGreen[x+1];
                T1wrong = speciesListGreen[getNextRedPosition(x, numEncounters)];
            }

            // get target species 2
            Species *T2;
            Species *T2wrong;

            // is it at marginal position?
            if (isMarginal(y, numEncounters)) {
                // check if over changeover limit (see notebook index_computations.nb)
                if (y > getChangeoverLimit(y, numEncounters)) {
                    // change to red
                    T2 = speciesListRed[0];
                    T2wrong = speciesListRed[0];
                } else {
                    T2 = speciesListGreen[0];

                    // wrong species
                    if (y==getChangeoverLimit(y, numEncounters))
                        T2wrong = speciesListRed[0];
                    else
                        T2wrong = speciesListGreen[0];
                }


            } else {
                T2 = speciesListGreen[y+1];
                T2wrong = speciesListGreen[getNextRedPosition(y, numEncounters)];
            }

            // print reaction
            std::stringstream rname;
            rname <<G1->id()<<" + "<<G2->id()<<" -> "<< T1->id()<<" + "<<T2->id();
            std::cout <<"Adding reaction "<<rname.str() <<"\n"<<std::flush;

            // and add it
            totnreacts++;
            Reaction *r = addReaction(rname.str(), kcorrect, G1, G2);
            r->setProductStoichiometry(T1, 1);
            if (T1 == T2)
                r->setProductStoichiometry(T2, 2);
            else
                r->setProductStoichiometry(T2, 1);

            // wrong reactions
            if (recognitionError > 0) {
                // first wrong
                std::stringstream rnamew1;
                rnamew1 << G1->id() << " + " << G2->id() <<" -> "<< T1wrong->id() << " + "<<T2->id();
                std::cout <<"Adding erreneous (first wrong) reaction "<<rnamew1.str()<<"\n"<<std::flush;
                totnreacts++;
                r = addReaction(rnamew1.str(), kwrong1, G1, G2);
                r->setProductStoichiometry(T1wrong, 1);
                if (T1wrong == T2)
                    r->setProductStoichiometry(T2, 2);
                else
                    r->setProductStoichiometry(T2, 1);

                // second wrong
                std::stringstream rnamew2;
                rnamew2 << G1->id() << " + " << G2->id() <<" -> "<< T1->id() << " + "<<T2wrong->id();
                std::cout <<"Adding erreneous (second wrong) reaction "<<rnamew2.str()<<"\n"<<std::flush;
                totnreacts++;
                r = addReaction(rnamew2.str(), kwrong1, G1, G2);
                r->setProductStoichiometry(T1, 1);
                if (T1== T2wrong)
                    r->setProductStoichiometry(T2wrong, 2);
                else
                    r->setProductStoichiometry(T2wrong, 1);

                // both wrong
                std::stringstream rnamewb;
                rnamewb << G1->id() << " + " << G2->id() <<" -> "<< T1wrong->id() << " + "<<T2wrong->id();
                std::cout <<"Adding erreneous (both wrong) reaction "<<rnamewb.str()<<"\n"<<std::flush;
                totnreacts++;
                r = addReaction(rnamewb.str(), kwrongb, G1, G2);
                r->setProductStoichiometry(T1wrong, 1);
                if (T1wrong == T2wrong)
                    r->setProductStoichiometry(T2wrong, 2);
                else
                    r->setProductStoichiometry(T2wrong, 1);

            }
        }
    }

    // Rxy+Rwz -> Rxy+1 + Rwz+1
    for (uint x=0; x<maxSpecies; x++) {
        for (uint y=x; y<maxSpecies; y++) {
            // get source species
            Species *R1 = speciesListRed[x];
            Species *R2 = speciesListRed[y];

            // get target species 1
            Species *T1;
            Species *T1wrong;

            // is it at marginal position?
            if (isMarginal(x, numEncounters)) {
                // check if over changeover limit (see notebook index_computations.nb)
                if (x >= getChangeoverLimit(x, numEncounters)) {
                    // change to red
                    T1 = speciesListRed[0];

                    // wrong species
                    if (x == getChangeoverLimit(x, numEncounters))
                        T1wrong = speciesListGreen[0];
                    else
                        T1wrong = speciesListRed[0];
                } else {
                    T1 = speciesListGreen[0];
                    T1wrong = speciesListGreen[0];
                }
            } else {
                T1 = speciesListRed[getNextRedPosition(x, numEncounters)];
                T1wrong = speciesListRed[x+1];
            }

            // get target species 2
            Species *T2;
            Species *T2wrong;

            // is it at marginal position?
            if (isMarginal(y, numEncounters)) {
                // check if over changeover limit (see notebook index_computations.nb)
                if (y >= getChangeoverLimit(y, numEncounters)) {
                    // change to red
                    T2 = speciesListRed[0];

                    // wrong species
                    if (y == getChangeoverLimit(y, numEncounters))
                        T2wrong = speciesListGreen[0];
                    else
                        T2wrong = speciesListRed[0];
                } else {
                    T2 = speciesListGreen[0];
                    T2wrong = speciesListGreen[0];
                }
            } else {
                T2 = speciesListRed[getNextRedPosition(y, numEncounters)];
                T2wrong = speciesListRed[y+1];
            }

            // print reaction
            std::stringstream rname;
            rname <<R1->id()<<" + "<<R2->id()<<" -> "<< T1->id()<<" + "<<T2->id();
            std::cout <<"Adding reaction "<<rname.str() <<"\n"<<std::flush;

            // and add it
            totnreacts++;
            Reaction *r = addReaction(rname.str(), kcorrect, R1, R2);
            r->setProductStoichiometry(T1, 1);
            if (T1 == T2)
                r->setProductStoichiometry(T2, 2);
            else
                r->setProductStoichiometry(T2, 1);

            // wrong reactions
            if (recognitionError > 0) {
                // first wrong
                std::stringstream rnamew1;
                rnamew1 << R1->id() <<" + " << R2->id() <<" -> " << T1wrong->id() << " + " << T2->id();
                std::cout <<"Adding erreneous (first wrong) reaction "<<rnamew1.str() << "\n" << std::flush;
                totnreacts++;
                r = addReaction(rnamew1.str(), kwrong1, R1, R2);
                r->setProductStoichiometry(T1wrong, 1);
                if (T1wrong == T2)
                    r->setProductStoichiometry(T2, 2);
                else
                    r->setProductStoichiometry(T2, 1);

                // second wrong
                std::stringstream rnamew2;
                rnamew2 << R1->id() <<" + " << R2->id() <<" -> " << T1->id() << " + " << T2wrong->id();
                std::cout <<"Adding erreneous (second wrong) reaction "<<rnamew2.str() << "\n" << std::flush;
                totnreacts++;
                r = addReaction(rnamew2.str(), kwrong1, R1, R2);
                r->setProductStoichiometry(T1, 1);
                if (T1== T2wrong)
                    r->setProductStoichiometry(T2wrong, 2);
                else
                    r->setProductStoichiometry(T2wrong, 1);

                // both wrong
                std::stringstream rnamewb;
                rnamewb << R1->id() <<" + " << R2->id() <<" -> " << T1wrong->id() << " + " << T2wrong->id();
                std::cout <<"Adding erreneous (both wrong) reaction "<<rnamewb.str() << "\n" << std::flush;
                totnreacts++;
                r = addReaction(rnamewb.str(), kwrongb, R1, R2);
                r->setProductStoichiometry(T1wrong, 1);
                if (T1wrong == T2wrong)
                    r->setProductStoichiometry(T2wrong, 2);
                else
                    r->setProductStoichiometry(T2wrong, 1);

            }
        }
    }
    std::cout <<"Added "<<totnreacts<<" reactions.\n";
    std::cout <<"Reaction propensities: no error = "<<kcorrect<<", one wrong = "<< kwrong1 <<" both wrong = "<<kwrongb
             <<"Sum = "<<(kcorrect + 2. * kwrong1 + kwrongb)<<"\n"<<std::flush;

    /*
    // Gxy+Gwz -> Gxy+1 + Gwz+1
    cg = 0;
    totnreacts=0;
    for (uint x=0; x<numEncounters; x++) {
        for (uint y=0; y<numEncounters-x; y++) {
            // to name the reaction
            std::ostringstream snamers;
            std::ostringstream snamerd;

            // find source and target species for green
            Species *Gxy = speciesListGreen[cg];
            snamers << "G"<<x<<y<<"("<<Gxy->id()<<")";

            Species *Txyp1;
            if ((x+y)==(numEncounters-1)) {
                // target species is either G00 or R00
                if (x>y) {
                    // turns red
                    Txyp1 = speciesListRed[0];
                    snamerd <<"R00"<<"("<<Txyp1->id()<<")";
                } else {
                    // stays green
                    Txyp1 = speciesListGreen[0];
                    snamerd <<"G00"<<"("<<Txyp1->id()<<")";
                }
            } else {
                // target species is Gxyp1
                Txyp1 = speciesListGreen[cg+1];
                snamerd <<"G"<<x<<y+1<<"("<<Txyp1->id()<<")";
            }

            // now pair with all other green robots
            for (uint w=x; w<numEncounters; w++) {
                for (uint z=x; z<numEncounters-w; z++) {
                    // compute index to second source species
                    // TODODODODO: you'll need to continue here ..
                    // come up with a function to compute the speciesindex from w and z
                    // and then assign cgg to it
                    // and then compare to the notebook with nencounters=3 (mesoscopic_reactions.nb)
                    // and then you need to adapt the HDF5 writer too
                    // and then just do a couple of runs with this problem and see how it compares to spatial
                    uint cgg=getSpeciesIndexFrom2D(w, z, numEncounters);

                    // find source and target species for red
                    Species *GGxy = speciesListGreen[cgg];
                    std::ostringstream sss;
                    std::ostringstream ssd;
                    sss << "G"<<w<<z<<"("<<GGxy->id()<<")";

                    Species *Twzp1;
                    if ((w+z)==(numEncounters-1)) {
                        // target species is either G00 or R00
                        if (w>z) {
                            // turns red
                            Twzp1 = speciesListRed[0];
                            ssd <<"R00"<<"("<<Twzp1->id()<<")";
                        } else {
                            // stays green
                            Twzp1 = speciesListGreen[0];
                            ssd <<"G00"<<"("<<Twzp1->id()<<")";
                        }
                    } else {
                        // target species is Gwzp1
                        Twzp1 = speciesListGreen[cgg+1];
                        ssd <<"G"<<w<<z+1<<"("<<Twzp1->id()<<")";
                    }

                    std::stringstream rname;
                    rname << snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str();
                    std::cout <<"Adding reaction "<< rname.str() <<" + " << ssd.str()<<".\n"<<std::flush;
                    totnreacts++;

                    Reaction *r = addReaction(rname.str(), reactionProb, Gxy, GGxy);
                    r->setProductStoichiometry(Txyp1, 1);
                    if (Twzp1 == Txyp1)
                        r->setProductStoichiometry(Twzp1, 2);
                    else
                        r->setProductStoichiometry(Twzp1, 1);

                    // increase counter
                    cgg++;
                } // pair with other green robots z
            } // pair with other green robots w

            // increase counter
            cg++;
        } // green robots y
    } // green robots x

    std::cout <<"Added a total of "<<totnreacts<<" reactions in the green self-reaction part.\n";
    exit(1);

    // Rxy+Rwz -> Rxy+1 + Rwz+1
    uint cr = 0;
    for (uint x=0; x<numEncounters; x++) {
        for (uint y=0; y<numEncounters-x; y++) {
            // to name the reaction
            std::ostringstream snamers;
            std::ostringstream snamerd;

            // find source and target species for green
            Species *Rxy = speciesListRed[cr];
            snamers << "R"<<x<<y<<"("<<Rxy->id()<<")";

            Species *Txp1y;
            if ((x+y)==(numEncounters-1)) {
                // target species is either G00 or R00
                if (x>=y) {
                    // turns red
                    Txp1y = speciesListRed[0];
                    snamerd <<"R00"<<"("<<Txp1y->id()<<")";
                } else {
                    // stays green
                    Txp1y = speciesListGreen[0];
                    snamerd <<"G00"<<"("<<Txp1y->id()<<")";
                }
            } else {
                // target species is Gxyp1
                Txp1y = speciesListRed[cr+(numEncounters-x)];
                snamerd <<"R"<<x+1<<y<<"("<<Txp1y->id()<<")";
            }

            // now pair with all other red robots
            uint crr=0;
            for (uint w=0; w<numEncounters; w++) {
                for (uint z=0; z<numEncounters-w; z++) {
                    // find source and target species for red
                    Species *RRxy = speciesListRed[crr];
                    std::ostringstream sss;
                    std::ostringstream ssd;
                    sss << "R"<<w<<z<<"("<<RRxy->id()<<")";

                    Species *Twp1z;
                    if ((w+z)==(numEncounters-1)) {
                        // target species is either G00 or R00
                        if (w>=z) {
                            // turns red
                            Twp1z = speciesListRed[0];
                            ssd <<"R00"<<"("<<Twp1z->id()<<")";
                        } else {
                            // stays green
                            Twp1z = speciesListGreen[0];
                            ssd <<"G00"<<"("<<Twp1z->id()<<")";
                        }
                    } else {
                        // target species is Rwzp1
                        Twp1z = speciesListRed[crr+(numEncounters-w)];
                        ssd <<"R"<<w+1<<z<<"("<<Twp1z->id()<<")";
                    }

                    std::stringstream rname;
                    rname << snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str()<<" + " << ssd.str();
                    std::cout <<"Adding reaction "<< rname.str() <<".\n";
                    Reaction *r = addReaction(rname.str(), reactionProb, Rxy, RRxy);
                    r->setProductStoichiometry(Txp1y, 1);
                    if (Txp1y == Twp1z)
                        r->setProductStoichiometry(Twp1z, 2);
                    else
                        r->setProductStoichiometry(Twp1z, 1);

                    // increase counter
                    crr++;
                } // pair with other red robots z
            } // pair with other red robots w

            // increase counter
            cr++;
        } // green robots y
    } // green robots x
    */
    // distribute species randomly
    /*
    Compartment *source = addCompartment("Source", 0, 0, dx-1, dy-1);
    source->setInitialAmount(speciesListRed[0], nReds, gpgmp::RandomDistribution);
    source->setInitialAmount(speciesListGreen[0], numMolecules-nReds, gpgmp::RandomDistribution);
    */

    // load init script
    loadInitScript((boost::filesystem::path(initScriptsPath) / "init_majority_no_diffusion.py").string());

    // add script parameters
    setParameter("numMolecules", numMolecules);
    setParameter("p", static_cast<float>(nReds)/static_cast<float>(numMolecules));

    setRegenerateInitStates(true);

}
Exemplo n.º 2
0
MajorityVoteProblem::MajorityVoteProblem(Real length, int dx, int dy,
                                         Real diffX, Real diffY,
                                         Real mux, Real muy,
                                         uint numMolecules, uint nReds,
                                         uint numEncounters,
                                         Real reactionProb,const std::string &initScriptsPath)
    : DiffusionModel(length, dx, dy), m_individual(false), m_isNonDiffusive(false)
{
    // this list will hold all red and green species
    // we need (i^2+i)/2 species per red and green
    // where i is the number of encounters after which the species "votes"
    uint maxSpecies = (numEncounters*numEncounters+numEncounters)/2;
    std::vector<gpgmp::Species *> speciesListRed(maxSpecies);
    std::vector<gpgmp::Species *> speciesListGreen(maxSpecies);

    // add species and reactions corresponding to scheme:
    // Rxy - red, has encountered x red and y green robots
    // Gxy - green, has encountered x red and y green robots
    uint c=0;
    for (uint i=0; i<numEncounters; i++) {
        for (uint j=0; j<numEncounters-i; j++) {
            // add species
            std::ostringstream snamered;
            snamered << "R"<<i<<j;
            speciesListRed[c] = addSpecies(snamered.str(), diffX);
            std::ostringstream snamegreen;
            snamegreen << "G"<<i<<j;
            speciesListGreen[c] = addSpecies(snamegreen.str(),diffX);

            // print out
            std::cout <<"Added species "<<snamered.str()<<" and "<<snamegreen.str()<<".\n";
            // increase counter;
            c++;
        }
    } // create species

    // set diffusivity and drift for species
    setParameter("diffX", diffX);
    setParameter("diffY", diffY);
    setParameter("driftX", mux);
    setParameter("driftY", muy);

    // set homogeneous diffusivity and drift
    setComputeDriftDiffusivityMethod(gpgmp::DT_HOMOGENEOUS);

    // add reactions
    // Gxy+Rwz -> Gx+1y + Rwz+1
    uint cg = 0;
    for (uint x=0; x<numEncounters; x++) {
        for (uint y=0; y<numEncounters-x; y++) {
            // to name the reaction
            std::ostringstream snamers;
            std::ostringstream snamerd;

            // find source and target species for green
            Species *Gxy = speciesListGreen[cg];
            snamers << "G"<<x<<y<<"("<<Gxy->id()<<")";

            Species *Txp1y;
            if ((x+y)==(numEncounters-1)) {
                // target species is either G00 or R00
                if (x>=y) {
                    // turns red
                    Txp1y = speciesListRed[0];
                    snamerd <<"R00"<<"("<<Txp1y->id()<<")";
                } else {
                    // stays greenstd::map<std::string, std::vector<Real> > &propertiesA = speciesA->getIndividualProperties();
                    Txp1y = speciesListGreen[0];
                    snamerd <<"G00"<<"("<<Txp1y->id()<<")";
                }
            } else {
                // target species is Gx+1y
                Txp1y = speciesListGreen[cg+(numEncounters-x)];
                snamerd <<"G"<<x+1<<y<<"("<<Txp1y->id()<<")";
            }

            // now pair with all red robots
            uint cr=0;
            for (uint w=0; w<numEncounters; w++) {
                for (uint z=0; z<numEncounters-w; z++) {
                    // find source and target species for red
                    Species *Rxy = speciesListRed[cr];
                    std::ostringstream sss;
                    std::ostringstream ssd;
                    sss << "R"<<w<<z << "("<<Rxy->id()<<")";

                    Species *Twzp1;
                    if ((w+z)==(numEncounters-1)) {
                        // target species is either G00 or R00
                        if (w>z) {
                            // turns red
                            Twzp1 = speciesListRed[0];
                            ssd <<"R00" << "("<<Twzp1->id()<<")";
                        } else {
                            // stays green
                            Twzp1 = speciesListGreen[0];
                            ssd <<"G00" << "("<<Twzp1->id()<<")";
                        }
                    } else {
                        // target species is Rw+1z
                        Twzp1 = speciesListRed[cr+1];
                        ssd <<"R"<<w<<z+1<< "("<<Twzp1->id()<<")";
                    }

                    std::ostringstream rname;
                    rname <<snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str()<<" + " << ssd.str();
                    std::cout <<"Adding reaction "<<rname.str()<<".\n";
                    Reaction *r = addReaction (rname.str(), reactionProb, Gxy, Rxy);
                    r->setProductStoichiometry(Txp1y, 1);
                    if (Txp1y == Twzp1)
                        r->setProductStoichiometry(Twzp1, 2);
                    else
                        r->setProductStoichiometry(Twzp1, 1);

                    // increase counter
                    cr++;
                } // pair with red robots z
            } // pair with red robots w

            // increase counter
            cg++;
        } // green robots y
    } // green robots x

    // Gxy+Gwz -> Gxy+1 + Gwz+1
    cg = 0;
    for (uint x=0; x<numEncounters; x++) {
        for (uint y=0; y<numEncounters-x; y++) {
            // to name the reaction
            std::ostringstream snamers;
            std::ostringstream snamerd;

            // find source and target species for green
            Species *Gxy = speciesListGreen[cg];
            snamers << "G"<<x<<y<<"("<<Gxy->id()<<")";

            Species *Txyp1;
            if ((x+y)==(numEncounters-1)) {
                // target species is either G00 or R00
                if (x>y) {
                    // turns red
                    Txyp1 = speciesListRed[0];
                    snamerd <<"R00"<<"("<<Txyp1->id()<<")";
                } else {
                    // stays green
                    Txyp1 = speciesListGreen[0];
                    snamerd <<"G00"<<"("<<Txyp1->id()<<")";
                }
            } else {
                // target species is Gxyp1
                Txyp1 = speciesListGreen[cg+1];
                snamerd <<"G"<<x<<y+1<<"("<<Txyp1->id()<<")";
            }

            // now pair with all other green robots
            uint cgg=0;
            for (uint w=0; w<numEncounters; w++) {
                for (uint z=0; z<numEncounters-w; z++) {
                    // find source and target species for red
                    Species *GGxy = speciesListGreen[cgg];
                    std::ostringstream sss;
                    std::ostringstream ssd;
                    sss << "G"<<w<<z<<"("<<GGxy->id()<<")";

                    Species *Twzp1;
                    if ((w+z)==(numEncounters-1)) {
                        // target species is either G00 or R00
                        if (w>z) {
                            // turns red
                            Twzp1 = speciesListRed[0];
                            ssd <<"R00"<<"("<<Twzp1->id()<<")";
                        } else {
                            // stays green
                            Twzp1 = speciesListGreen[0];
                            ssd <<"G00"<<"("<<Twzp1->id()<<")";
                        }
                    } else {
                        // target species is Gwzp1
                        Twzp1 = speciesListGreen[cgg+1];
                        ssd <<"G"<<w<<z+1<<"("<<Twzp1->id()<<")";
                    }

                    std::stringstream rname;
                    rname << snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str();
                    std::cout <<"Adding reaction "<< rname.str() <<" + " << ssd.str()<<".\n";

                    Reaction *r = addReaction(rname.str(), reactionProb, Gxy, GGxy);
                    r->setProductStoichiometry(Txyp1, 1);
                    if (Twzp1 == Txyp1)
                        r->setProductStoichiometry(Twzp1, 2);
                    else
                        r->setProductStoichiometry(Twzp1, 1);

                    // increase counter
                    cgg++;
                } // pair with other green robots z
            } // pair with other green robots w

            // increase counter
            cg++;
        } // green robots y
    } // green robots x

    // Rxy+Rwz -> Rxy+1 + Rwz+1
    uint cr = 0;
    for (uint x=0; x<numEncounters; x++) {
        for (uint y=0; y<numEncounters-x; y++) {
            // to name the reaction
            std::ostringstream snamers;
            std::ostringstream snamerd;

            // find source and target species for green
            Species *Rxy = speciesListRed[cr];
            snamers << "R"<<x<<y<<"("<<Rxy->id()<<")";

            Species *Txp1y;
            if ((x+y)==(numEncounters-1)) {
                // target species is either G00 or R00
                if (x>=y) {
                    // turns red
                    Txp1y = speciesListRed[0];
                    snamerd <<"R00"<<"("<<Txp1y->id()<<")";
                } else {
                    // stays green
                    Txp1y = speciesListGreen[0];
                    snamerd <<"G00"<<"("<<Txp1y->id()<<")";
                }
            } else {
                // target species is Gxyp1
                Txp1y = speciesListRed[cr+(numEncounters-x)];
                snamerd <<"R"<<x+1<<y<<"("<<Txp1y->id()<<")";
            }

            // now pair with all other red robots
            uint crr=0;
            for (uint w=0; w<numEncounters; w++) {
                for (uint z=0; z<numEncounters-w; z++) {
                    // find source and target species for red
                    Species *RRxy = speciesListRed[crr];
                    std::ostringstream sss;
                    std::ostringstream ssd;
                    sss << "R"<<w<<z<<"("<<RRxy->id()<<")";

                    Species *Twp1z;
                    if ((w+z)==(numEncounters-1)) {
                        // target species is either G00 or R00
                        if (w>=z) {
                            // turns red
                            Twp1z = speciesListRed[0];
                            ssd <<"R00"<<"("<<Twp1z->id()<<")";
                        } else {
                            // stays green
                            Twp1z = speciesListGreen[0];
                            ssd <<"G00"<<"("<<Twp1z->id()<<")";
                        }
                    } else {
                        // target species is Rwzp1
                        Twp1z = speciesListRed[crr+(numEncounters-w)];
                        ssd <<"R"<<w+1<<z<<"("<<Twp1z->id()<<")";
                    }

                    std::stringstream rname;
                    rname << snamers.str()<<" + "<<sss.str()<<" -> "<<snamerd.str()<<" + " << ssd.str();
                    std::cout <<"Adding reaction "<< rname.str() <<".\n";
                    Reaction *r = addReaction(rname.str(), reactionProb, Rxy, RRxy);
                    r->setProductStoichiometry(Txp1y, 1);
                    if (Txp1y == Twp1z)
                        r->setProductStoichiometry(Twp1z, 2);
                    else
                        r->setProductStoichiometry(Twp1z, 1);

                    // increase counter
                    crr++;
                } // pair with other red robots z
            } // pair with other red robots w

            // increase counter
            cr++;
        } // green robots y
    } // green robots x

    // distribute species randomly
    /*
    Compartment *source = addCompartment("Source", 0, 0, dx-1, dy-1);
    source->setInitialAmount(speciesListRed[0], nReds, gpgmp::RandomDistribution);
    source->setInitialAmount(speciesListGreen[0], numMolecules-nReds, gpgmp::RandomDistribution);
    */

    // load init script
    loadInitScript((boost::filesystem::path(initScriptsPath) / "init_majority.py").string());

    // add script parameters
    setParameter("numMolecules", numMolecules);
    setParameter("p", static_cast<float>(nReds)/static_cast<float>(numMolecules));

    setRegenerateInitStates(true);
}