예제 #1
0
/* Update the group and model sufficient statistics based on assignments qZj.
 *
 *  mutable: the clusters (add sufficient stats).
 *  returns: the number of observations in each cluster for this groups.
 */
template <class C> ArrayXd updateSS (
    const MatrixXd& Xj,   // Observations in group j
    const MatrixXd& qZj,  // Observations to group mixture assignments
    vector<C>& clusters,  // Cluster Distributions
    const bool sparse     // Do sparse updates to groups
    )
{
  const unsigned int K = qZj.cols();

  const ArrayXd Njk = qZj.colwise().sum();  // count obs. in this group
  ArrayXi Kful = ArrayXi::Zero(1),          // Initialise and set K = 1 defaults
          Kemp = ArrayXi::Zero(0);

  // Find empty clusters if sparse
  if ( (sparse == false) && (K > 1) )
    Kful = ArrayXi::LinSpaced(Sequential, K, 0, K-1);
  else if (sparse == true)
    arrfind((Njk >= ZEROCUTOFF), Kful, Kemp);

  const unsigned int nKful = Kful.size();

  // Sufficient statistics - with observations
  for (unsigned int k = 0; k < nKful; ++k)
  {
#ifdef WITH_OMP
    #pragma omp critical
#endif
    clusters[Kful(k)].addobs(qZj.col(Kful(k)), Xj);
  }

  return Njk;
}
예제 #2
0
        ArrayXi perm_nodes_2_locations(const PermutationMatrix<Dynamic, Dynamic, int> &_perm_nodes)
        {
            ArrayXi indices = _perm_nodes.indices().array();

            for (unsigned int i = 0; i<indices.size(); i++)
                indices = (indices > indices(i)).select(indices + nodes_.at(i).dim-1, indices);

            return indices;
        }
예제 #3
0
        void nodePermutation2VariablesPermutation(const PermutationMatrix<Dynamic, Dynamic, int> &_perm_nodes, PermutationMatrix<Dynamic, Dynamic, int> &perm_variables)
        {
            ArrayXi locations = perm_nodes_2_locations(_perm_nodes);

            int last_idx = 0;
            for (unsigned int i = 0; i<locations.size(); i++)
            {
                perm_variables.indices().segment(last_idx, nodes_.at(i).dim) = VectorXi::LinSpaced(nodes_.at(i).dim, locations(i), locations(i)+nodes_.at(i).dim-1);
                last_idx += nodes_.at(i).dim;
            }
        }
예제 #4
0
/* The Variational Bayes Expectation step for each group.
 *
 *  mutable: Group assignment probabilities, qZj
 *  returns: The complete-data (X,Z) free energy E[log p(X,Z)/q(Z)] for group j.
 *  throws: invalid_argument rethrown from other functions.
 */
template <class W, class C> double vbexpectation (
    const MatrixXd& Xj,         // Observations in group J
    const W& weights,           // Group Weight parameter distribution
    const vector<C>& clusters,  // Cluster parameter distributions
    MatrixXd& qZj,              // Observations to group mixture assignments
    const bool sparse           // Do sparse updates to groups
    )
{
  const int K  = clusters.size(),
            Nj = Xj.rows();

  // Get log marginal weight likelihoods
  const ArrayXd E_logZ = weights.Elogweight();

  // Initialise and set K = 1 defaults for cluster counts
  ArrayXi Kful = ArrayXi::Zero(1), Kemp = ArrayXi::Zero(0);

  // Find empty clusters if sparse
  if ( (sparse == false) && (K > 1) )
    Kful = ArrayXi::LinSpaced(Sequential, K, 0, K-1);
  else if (sparse == true)
    arrfind((weights.getNk() >= ZEROCUTOFF), Kful, Kemp);

  const int nKful = Kful.size(),
            nKemp = Kemp.size();

  // Find Expectations of log joint observation probs -- allow sparse evaluation
  MatrixXd logqZj(Nj, nKful);

  for (int k = 0; k < nKful; ++k)
    logqZj.col(k) = E_logZ(Kful(k)) + clusters[Kful(k)].Eloglike(Xj).array();

  // Log normalisation constant of log observation likelihoods
  const VectorXd logZzj = logsumexp(logqZj);

  // Make sure qZ is the right size, this is a nop if it is
  qZj.resize(Nj, K);

  // Normalise and Compute Responsibilities -- again allow sparse evaluation
  for (int k = 0; k < nKful; ++k)
    qZj.col(Kful(k)) = ((logqZj.col(k) - logZzj).array().exp()).matrix();

  // Empty Cluster Responsabilities
  for (int k = 0; k < nKemp; ++k)
    qZj.col(Kemp(k)).setZero();

  return -logZzj.sum();
}
	BlockMatrixXcd random_hermitian(ArrayXi sizes) {

	if (log) std::cout << "A random hermitian matrix is made!" << std::endl;

	const long full_size = sizes.sum();

	if (log) std::cout << "We initialize with zeros." << std::endl;

	BlockMatrixXcd result = MatrixXcd::Zero(full_size,full_size);

	if (log) std::cout << "We define blocks." << std::endl;

	result.setBlocks(sizes);

	if (log) std::cout << "We randomly set the diagonal as well as lower and upper diagonal blocks." << std::endl;

	for(int i = 0; i < sizes.size(); i++)
	{
		if (log) std::cout << "Diagonal block " << i << " is set." << std::endl;

		result.block(i, i) = MatrixXcd::Random(sizes[i],sizes[i]);

		if( i < sizes.size() - 1)
		{
			if (log) std::cout << "Upper diagonal block " << i << " is set." << std::endl;
			result.block(i + 1, i) = MatrixXcd::Random(sizes[i + 1], sizes[i]);
			if (log) std::cout << "Lower diagonal block " << i << " is set." << std::endl;
			result.block(i, i + 1) = MatrixXcd::Random(sizes[i], sizes[i + 1]);
		}
	}

	if (log) std::cout << "The matrix is added to its adjoint." << std::endl;
	
	result += result.adjoint().eval();

	if (log) std::cout << "The matrix is finished." << std::endl;

	return result;
}
예제 #6
0
//get new Ori and Pos arrays for the child after recombination
void AnimalClass::sampleMyPosOri(AnimalClass& father,
                               AnimalClass& mother)
{
    sireId  = father.myId;
    damId   = mother.myId;
	
	chromosome *currentFatherChrom;
	chromosome *currentMotherChrom;
	
	unsigned numChromosomePair = G.get_num_chrom();
    
    //construct paternal chromosome for myId
    ArrayXf tempPos;
    ArrayXi tempOri;
    tempPos.resize(100000);
    tempOri.resize(100000);
    
    for(unsigned i=0;i<numChromosomePair;i++){
        double chrLength = G[i].chr_length;
        unsigned binomialN = chrLength*3 + 1;
        vector<float> rPos;
        binomial_distribution<int> Binom(binomialN,chrLength/binomialN);
        int numCrossover    =   Binom(randGen);
        
        uniform_real_distribution<float> u(0,1);
        for (unsigned k=0; k<numCrossover; k++) {
            rPos.push_back(chrLength*u(randGen));
        }
        rPos.push_back(chrLength);
        sort(rPos.begin(),rPos.end());
        

        unsigned   startPosParent=0;
        unsigned   startPosMe=0;
        
        currentFatherChrom = (u(randGen)<0.5)?&father.GenomePat[i]:&father.GenomeMat[i];

        for(unsigned j=0;j<rPos.size();j++){

            unsigned numCopy=(currentFatherChrom->pos < rPos[j]).count()-startPosParent;
            tempPos.block(startPosMe,0,numCopy,1)=currentFatherChrom->pos.block(startPosParent,0,numCopy,1);
            tempOri.block(startPosMe,0,numCopy,1)=currentFatherChrom->ori.block(startPosParent,0,numCopy,1);
            
            currentFatherChrom= (currentFatherChrom==&father.GenomePat[i])?&father.GenomeMat[i]:&father.GenomePat[i];
            
            startPosParent=(currentFatherChrom->pos < rPos[j]).count();
            startPosMe+=numCopy;
            tempPos(startPosMe)=rPos[j];
            tempOri(startPosMe)=currentFatherChrom->ori(startPosParent-1);
            startPosMe++;
        } //the length of tempPos should be startPosMe now. Tricky here.
        
//        unsigned posLengthMinusOne=startPosMe-1;
//        unsigned nonzero=(tempPos.block(1,0,posLengthMinusOne,1)-tempPos.block(0,0,posLengthMinusOne,1)).count()+1;
//        GenomePat[i].pos.resize(nonzero-1);
//        GenomePat[i].ori.resize(nonzero-1);
       
        unsigned keep=0;
        GenomePat[i].pos.resize(startPosMe);
        GenomePat[i].ori.resize(startPosMe);
        GenomePat[i].pos[0]=tempPos[0];
        GenomePat[i].ori[0]=tempOri[0];

        for(unsigned m=1;m < startPosMe-1; m++){

            if(tempOri[m]!=tempOri[m-1]){
            keep=keep+1;
            GenomePat[i].pos[keep]=tempPos[m];
            GenomePat[i].ori[keep]=tempOri[m];
            }
        }
        
        unsigned PosOriSize=keep+1;
        GenomePat[i].pos.conservativeResize(PosOriSize);
        GenomePat[i].ori.conservativeResize(PosOriSize);

    }
    ///
    ///construct maternal chromosome for myId
    for(unsigned i=0;i<numChromosomePair;i++){
        double chrLength = G[i].chr_length;
        unsigned binomialN = chrLength*3 + 1;
        vector<float> rPos;
        binomial_distribution<int> Binom(binomialN,chrLength/binomialN);
        int numCrossover    =   Binom(randGen);
        
        uniform_real_distribution<float> u(0,1);
        for (unsigned k=0; k<numCrossover; k++) {
            float rPos_Hao=chrLength*u(randGen);
                rPos.push_back(rPos_Hao);
        }

        rPos.push_back(chrLength);
        sort(rPos.begin(),rPos.end());
        
        unsigned   startPosParent=0;
        unsigned   startPosMe=0;
   
        currentMotherChrom = (u(randGen)<0.5)?&mother.GenomePat[i]:&mother.GenomeMat[i];
        
        for(unsigned j=0;j<rPos.size();j++){
            
            unsigned numCopy=(currentMotherChrom->pos < rPos[j]).count()-startPosParent;
            tempPos.block(startPosMe,0,numCopy,1)=currentMotherChrom->pos.block(startPosParent,0,numCopy,1);
            tempOri.block(startPosMe,0,numCopy,1)=currentMotherChrom->ori.block(startPosParent,0,numCopy,1);
            
            currentMotherChrom= (currentMotherChrom==&mother.GenomePat[i])?&mother.GenomeMat[i]:&mother.GenomePat[i];
            
            startPosParent=(currentMotherChrom->pos < rPos[j]).count();
            startPosMe+=numCopy;
            tempPos(startPosMe)=rPos[j];
            tempOri(startPosMe)=currentMotherChrom->ori(startPosParent-1);
            startPosMe++;
            
        }
        
//        unsigned posLengthMinusOne=startPosMe-1;
//        unsigned nonzero=(tempPos.block(1,0,posLengthMinusOne,1)-tempPos.block(0,0,posLengthMinusOne,1)).count()+1;
//        GenomeMat[i].pos.resize(nonzero-1);
//        GenomeMat[i].ori.resize(nonzero-1);

        unsigned keep=0;
        GenomeMat[i].pos.resize(startPosMe);
        GenomeMat[i].ori.resize(startPosMe);
        GenomeMat[i].pos[0]=tempPos[0];
        GenomeMat[i].ori[0]=tempOri[0];
        
        
        for(unsigned m=1;m < startPosMe-1; m++){
            
            if(tempOri[m]!=tempOri[m-1]){
                keep=keep+1;
                GenomeMat[i].pos[keep]=tempPos[m];
                GenomeMat[i].ori[keep]=tempOri[m];
            }
            
        }
        
        unsigned PosOriSize=keep+1;
        GenomeMat[i].pos.conservativeResize(PosOriSize);
        GenomeMat[i].ori.conservativeResize(PosOriSize);

    }
}