int main() { TreeTemplate<Node>* tree = TreeTemplateTools::parenthesisToTree("((A:0.001, B:0.002):0.003,C:0.01,D:0.1);"); cout << tree->getNumberOfLeaves() << endl; vector<int> ids = tree->getNodesId(); //------------- NucleicAlphabet* alphabet = new DNA(); SubstitutionModel* model = new GTR(alphabet, 1, 0.2, 0.3, 0.4, 0.4, 0.1, 0.35, 0.35, 0.2); //DiscreteDistribution* rdist = new GammaDiscreteDistribution(4, 0.4, 0.4); DiscreteDistribution* rdist = new ConstantDistribution(1.0); HomogeneousSequenceSimulator simulator(model, rdist, tree); unsigned int n = 100000; map<int, RowMatrix<unsigned int> > counts; for (size_t j = 0; j < ids.size() - 1; ++j) //ignore root, the last id counts[ids[j]].resize(4, 4); for (unsigned int i = 0; i < n; ++i) { RASiteSimulationResult* result = simulator.dSimulate(); for (size_t j = 0; j < ids.size() - 1; ++j) { //ignore root, the last id result->getMutationPath(ids[j]).getEventCounts(counts[ids[j]]); } delete result; } map<int, RowMatrix<double> >freqs; map<int, double> sums; for (size_t k = 0; k < ids.size() - 1; ++k) { //ignore root, the last id RowMatrix<double>* freqsP = &freqs[ids[k]]; RowMatrix<unsigned int>* countsP = &counts[ids[k]]; freqsP->resize(4, 4); for (unsigned int i = 0; i < 4; ++i) for (unsigned int j = 0; j < 4; ++j) (*freqsP)(i, j) = static_cast<double>((*countsP)(i, j)) / (static_cast<double>(n)); //For now we simply compare the total number of substitutions: sums[ids[k]] = MatrixTools::sumElements(*freqsP); cout << "Br" << ids[k] << " BrLen = " << tree->getDistanceToFather(ids[k]) << " counts = " << sums[ids[k]] << endl; MatrixTools::print(*freqsP); } //We should compare this matrix with the expected one! for (size_t k = 0; k < ids.size() - 1; ++k) { //ignore root, the last id if (abs(sums[ids[k]] - tree->getDistanceToFather(ids[k])) > 0.01) { delete tree; delete alphabet; delete model; delete rdist; return 1; } } //------------- delete tree; delete alphabet; delete model; delete rdist; //return (abs(obs - 0.001) < 0.001 ? 0 : 1); return 0; }
void DualityDiagram::compute_(const Matrix<double>& matrix, double tol, bool verbose) { size_t rowNb = matrix.getNumberOfRows(); size_t colNb = matrix.getNumberOfColumns(); // If there are less rows than columns, the variance-covariance or correlation matrix is obtain differently (see below) bool transpose = (rowNb < colNb); // The initial matrix is multiplied by the square root of the row weigths. vector<double> rW(rowWeights_); for (unsigned int i = 0; i < rowWeights_.size(); i++) { rW[i] = sqrt(rowWeights_[i]); } RowMatrix<double> M1(rowNb, colNb); MatrixTools::hadamardMult(matrix, rW, M1, true); // The resulting matrix is then multiplied by the square root of the column weigths. vector<double> cW(colWeights_); for (unsigned int i = 0; i < colWeights_.size(); i++) { cW[i] = sqrt(colWeights_[i]); } RowMatrix<double> M2; MatrixTools::hadamardMult(M1, cW, M2, false); // The variance-covariance (if the data is centered) or the correlation (if the data is centered and normalized) matrix is calculated RowMatrix<double> tM2; MatrixTools::transpose(M2, tM2); RowMatrix<double> M3; if (!transpose) MatrixTools::mult(tM2, M2, M3); else MatrixTools::mult(M2, tM2, M3); EigenValue<double> eigen(M3); if (!eigen.isSymmetric()) throw Exception("DualityDiagram (constructor). The variance-covariance or correlation matrix should be symmetric..."); eigenValues_ = eigen.getRealEigenValues(); eigenVectors_ = eigen.getV(); // How many significant axes have to be conserved? size_t rank = 0; for (size_t i = eigenValues_.size(); i > 0; i--) { if ((eigenValues_[i - 1] / eigenValues_[eigenValues_.size() - 1]) > tol) rank++; } if (nbAxes_ <=0) { throw Exception("DualityDiagram (constructor). The number of axes to keep must be positive."); } if (nbAxes_ > rank) { if (verbose) ApplicationTools::displayWarning("The number of axes to kept has been reduced to conserve only significant axes"); nbAxes_ = rank; } /*The eigen values are initially sorted into ascending order by the 'eigen' function. Here the significant values are sorted in the other way around.*/ vector<double> tmpEigenValues(nbAxes_); size_t cpt = 0; for (size_t i = eigenValues_.size(); i > (eigenValues_.size() - nbAxes_); i--) { tmpEigenValues[cpt] = eigenValues_[i-1]; cpt++; } eigenValues_ = tmpEigenValues; for (vector<double>::iterator it = rowWeights_.begin(); it != rowWeights_.end(); it++) { if (*it == 0.) *it = 1.; } for (vector<double>::iterator it = colWeights_.begin(); it != colWeights_.end(); it++) { if (*it == 0.) *it = 1.; } vector<double> dval(nbAxes_); for (size_t i = 0; i < dval.size(); i++) { dval[i] = sqrt(eigenValues_[i]); } vector<double> invDval(nbAxes_); for (size_t i = 0; i < invDval.size(); i++) { invDval[i] = 1. / sqrt(eigenValues_[i]); } // Calculation of the row and column coordinates as well as the principal axes and components: if (!transpose) { vector<double> tmpColWeights(colNb); for (unsigned int i = 0; i < colWeights_.size(); i++) { tmpColWeights[i] = 1. / sqrt(colWeights_[i]); } // The eigen vectors are placed in the same order as their corresponding eigen value in eigenValues_. RowMatrix<double> tmpEigenVectors; tmpEigenVectors.resize(eigenVectors_.getNumberOfRows(), nbAxes_); size_t cpt2 = 0; for (size_t i = eigenVectors_.getNumberOfColumns(); i > (eigenVectors_.getNumberOfColumns() - nbAxes_); i--) { for (unsigned int j = 0; j < eigenVectors_.getNumberOfRows(); j++) { tmpEigenVectors(j, cpt2) = eigenVectors_(j, i-1); } cpt2++; } // matrix of principal axes MatrixTools::hadamardMult(tmpEigenVectors, tmpColWeights, ppalAxes_, true); // matrix of row coordinates RowMatrix<double> tmpRowCoord_; tmpRowCoord_.resize(rowNb, nbAxes_); MatrixTools::hadamardMult(matrix, colWeights_, tmpRowCoord_, false); MatrixTools::mult(tmpRowCoord_, ppalAxes_, rowCoord_); // matrix of column coordinates MatrixTools::hadamardMult(ppalAxes_, dval, colCoord_, false); // matrix of principal components MatrixTools::hadamardMult(rowCoord_, invDval, ppalComponents_, false); } else { vector<double> tmpRowWeights(rowNb); for (unsigned int i = 0; i < rowWeights_.size(); i++) { tmpRowWeights[i] = 1. / sqrt(rowWeights_[i]); } // The eigen vectors are placed in the same order as their corresponding eigen value in eigenValues_. RowMatrix<double> tmpEigenVectors; tmpEigenVectors.resize(eigenVectors_.getNumberOfRows(), nbAxes_); size_t cpt2 = 0; for (size_t i = eigenVectors_.getNumberOfColumns(); i > (eigenVectors_.getNumberOfColumns() - nbAxes_); i--) { for (size_t j = 0; j < eigenVectors_.getNumberOfRows(); j++) { tmpEigenVectors(j, cpt2) = eigenVectors_(j, i-1); } cpt2++; } // matrix of principal components MatrixTools::hadamardMult(tmpEigenVectors, tmpRowWeights, ppalComponents_, true); // matrix of column coordinates RowMatrix<double> tmpColCoord_; tmpColCoord_.resize(colNb, nbAxes_); MatrixTools::hadamardMult(matrix, rowWeights_, tmpColCoord_, true); RowMatrix<double> tTmpColCoord_; MatrixTools::transpose(tmpColCoord_, tTmpColCoord_); MatrixTools::mult(tTmpColCoord_, ppalComponents_, colCoord_); // matrix of row coordinates MatrixTools::hadamardMult(ppalComponents_, dval, rowCoord_, false); // matrix of principal axes MatrixTools::hadamardMult(colCoord_, invDval, ppalAxes_, false); } }