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; }
RowMatrix<T> operator~(const RowMatrix<T> &r) { RowMatrix<T> m{ r.cols(), r.rows() }; for (size_t i = 0; i < r.rows(); ++i) { for (size_t j = 0; j < r.cols(); ++j) { m[j][i] = r[i][j]; } } m.compress(); return m; }
vector<vector<double>> Alignment::get_q_matrix() { if(!model) throw Exception("No model has been set."); RowMatrix<double> gen = model->getGenerator(); size_t nrow = gen.getNumberOfRows(); size_t ncol = gen.getNumberOfColumns(); auto q = vector<vector<double>>(nrow, vector<double>(ncol, 0)); for (size_t i = 0; i < nrow; ++i) { for (size_t j = 0; j < ncol; ++j) { q[i][j] = gen(i, j); } } return q; }
vector<vector<double>> Alignment::get_p_matrix(double time) { if(!model) throw Exception("No model has been set."); RowMatrix<double> pijt = model->getPij_t(time); size_t nrow = pijt.getNumberOfRows(); size_t ncol = pijt.getNumberOfColumns(); auto p = vector<vector<double>>(nrow, vector<double>(ncol, 0)); for (size_t i = 0; i < nrow; ++i) { for (size_t j = 0; j < ncol; ++j) { p[i][j] = pijt(i, j); } } return p; }
vector<vector<double>> Alignment::get_exchangeabilities() { if(!model) throw Exception("No model has been set."); RowMatrix<double> exch = model->getExchangeabilityMatrix(); size_t nrow = exch.getNumberOfRows(); size_t ncol = exch.getNumberOfColumns(); auto s = vector<vector<double>>(nrow, vector<double>(ncol, 0)); for (size_t i = 0; i < nrow; ++i) { vector<double> row; for (size_t j = 0; j < ncol; ++j) { s[i][j] = exch(i, j); } } return s; }
GLboolean CyclicCurve3::BlendingFunctionValues(GLdouble u,RowMatrix<GLdouble>& values) const { values.ResizeColumns(2 * _n + 1); for(GLuint i = 0; i < 2 * _n + 1; ++i) { values[i] = _c_n * pow(1.0 + cos(u - i * _lambda_n),(GLint)_n); } return GL_TRUE; }
GLboolean HermitePatch::VBlendingFunctionValues(GLdouble v_knot, RowMatrix<GLdouble> &blending_values) const { if (v_knot<0.0 || v_knot>1.0) return GL_FALSE; blending_values.ResizeColumns(4); GLdouble v=v_knot, v2=v*v, v3=v2*v; blending_values(0) = 2*v3 - 3*v2 + 1; blending_values(1) = -2*v3 + 3*v2; blending_values(2) = v3 - 2*v2 + v; blending_values(3) = v3 - v2; return GL_TRUE; }
GLboolean HermitePatch::UBlendingFunctionValues(GLdouble u_knot, RowMatrix<GLdouble> &blending_values) const { if (u_knot<0.0 || u_knot>1.0) return GL_FALSE; blending_values.ResizeColumns(4); GLdouble u=u_knot, u2=u*u, u3=u2*u; blending_values(0) = 2*u3 - 3*u2 + 1; blending_values(1) = -2*u3 + 3*u2; blending_values(2) = u3 - 2*u2 + u; blending_values(3) = u3 - u2; return GL_TRUE; }
RowMatrix<T> operator*(const RowMatrix<T> &lhs, const RowMatrix<T> &rhs) { RowMatrix<T> m{ lhs.rows(), rhs.cols() }; for (size_t i = 0; i < lhs.rows(); ++i) { for (size_t j = 0; j < rhs.cols(); ++j) { T accum = 0; for (size_t k = lhs.row_left(i); k < lhs.row_right(i); ++k) { accum += lhs[i][k] * rhs[k][j]; } m[i][j] = accum; } } m.compress(); return m; }
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); } }