inline const NumericVector * E (const NumericMatrix& mtx){ const NumericVector * rm=rowMeans(mtx); const NumericVector * jt=jitter(*rm); delete rm; return jt; }
double Mean_Square_Error(NCluster *a, RContext *k, int s, int t){ IOSet *cols = a->GetSetById(s); IOSet *rows = a->GetSetById(t); double mse=0; double allCnt; // cnt of all values in the subspace double allSum=0; //the sum of all values double allMean=0; vector<double> rowMeans(rows->Size()); vector<double> colMeans(cols->Size()); //get row means and total mean for(int i=0; i < rows->Size();i++){ RSet *lclRow = k->GetSet(t,rows->At(i)); RSet *subSpace = lclRow->GetSubspace(cols); if(subSpace->Size() > 0){ double sum = subSpace->Sum(); allSum += sum; allCnt += subSpace->Size(); rowMeans.push_back( sum/(double)cols->Size()); } delete subSpace; } allMean = allSum/allCnt; //get col means for(int i=0; i < cols->Size(); i++){ RSet *lclCol = k->GetSet(s,cols->At(i)); RSet *subSpace = lclCol->GetSubspace(rows); if(subSpace->Size() > 0){ colMeans.push_back(subSpace->Mean()); } delete subSpace; } //now sum for all elements for(int i=0; i < rows->Size();i++){ RSet *lclRow = k->GetSet(t,rows->At(i)); RSet *subSpace = lclRow->GetSubspace(cols); if(subSpace->Size() > 0){ for(int j=0; j < subSpace->Size(); j++){ pair<int,double> val = subSpace->At(cols->At(j)); if(val.first != -1) mse += pow(val.second-rowMeans[j]-colMeans[j]+allMean,2); } } delete subSpace; } return mse/allCnt; }
void PCoA::project(const Matrix& distMatrix) { if(distMatrix.size() == 0) return; m_projectedData = distMatrix; // Center squared distance matrix // Step 1: Square entries and divide by -2.0 for(uint r = 0; r < m_projectedData.size(); ++r) { for(uint c = 0; c < m_projectedData.size(); ++c) { m_projectedData[r][c] = m_projectedData.at(r).at(c)*m_projectedData.at(r).at(c) / -2.0; } } // Step 2: Calculate column and row means std::vector<double> colMeans(m_projectedData.size(), 0); std::vector<double> rowMeans(m_projectedData.size(), 0); for(uint r = 0; r < m_projectedData.size(); ++r) { for(uint c = 0; c < m_projectedData.size(); ++c) { rowMeans[r] += m_projectedData.at(r).at(c); colMeans[c] += m_projectedData.at(r).at(c); } } for(uint i = 0; i < m_projectedData.size(); ++i) { rowMeans[i] /= m_projectedData.size(); colMeans[i] /= m_projectedData.size(); } // Step 3: Calculate matrix mean double matrixMean = 0; for(uint i = 0; i < m_projectedData.size(); ++i) matrixMean += rowMeans.at(i); matrixMean /= m_projectedData.size(); // Step 4: Calculate actual "centered" distance matrix for(uint r = 0; r < m_projectedData.size(); ++r) { for(uint c = 0; c < m_projectedData.size(); ++c) { m_projectedData[r][c] = m_projectedData.at(r).at(c) - rowMeans.at(r) - colMeans.at(c) + matrixMean; } } // Step 5: Calculate eigenvectors and eigenvalues double* M = new double[m_projectedData.size() * m_projectedData.size()]; // input matrix double* U = new double[m_projectedData.size() * m_projectedData.size()]; // eigenvectors double* D = new double[m_projectedData.size()]; // real component of eigenvalues double* E = new double[m_projectedData.size()]; // imaginary component of eigenvalues for(uint r = 0; r < m_projectedData.size(); ++r) { for(uint c = 0; c < m_projectedData.size(); ++c) { M[c+r*m_projectedData.size()] = m_projectedData.at(r).at(c); } } EigDecomp(M, U, D, E, m_projectedData.size()); // Step 6: Find desending order of eigenvalues for(uint i = 0; i < m_projectedData.size(); ++i) D[i] = fabs(D[i]); m_eigenValues.clear(); m_sumEigenvalues = 0; for(uint i = 0; i < m_projectedData.size(); ++i) { m_sumEigenvalues += D[i]; m_eigenValues.push_back(D[i]); } std::sort(m_eigenValues.begin(), m_eigenValues.end(), std::greater<double>()); std::vector<uint> indexOrder; for(uint i = 0; i < m_projectedData.size(); ++i) { bool bBreak = false; for(uint j = 0; j < m_projectedData.size() && !bBreak; ++j) { if(m_eigenValues.at(i) == D[j]) { indexOrder.push_back(j); bBreak = true; } } } // Step 7: Calculate variance and summed variance for each embedded dimension m_variance.clear(); m_sumVariance.clear(); for(uint i = 0; i < m_projectedData.size(); ++i) { m_variance.push_back(m_eigenValues.at(i) / m_sumEigenvalues); if(i == 0) m_sumVariance.push_back(m_variance.at(0)); else m_sumVariance.push_back(m_sumVariance.at(i-1) + m_variance.at(i)); } // Step 8: Transform eigenvector matrix into new embedded space for(uint i = 0; i < m_projectedData.size(); ++i) { D[i] = sqrt(D[i]); for(uint r = 0; r < m_projectedData.size(); ++r) { for(uint c = 0; c < m_projectedData.size(); ++c) { m_projectedData[r][c] = U[indexOrder.at(c)+r*m_projectedData.size()]*D[indexOrder.at(c)]; } } } delete[] M; delete[] U; delete[] D; delete[] E; }