/* 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; }
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; }
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; } }
/* 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; }
//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); } }