void ba81NormalQuad::layer::detectTwoTier(Eigen::ArrayBase<T1> ¶m, Eigen::MatrixBase<T2> &mean, Eigen::MatrixBase<T3> &cov) { if (mean.rows() < 3) return; std::vector<int> orthogonal; Eigen::Matrix<Eigen::DenseIndex, Eigen::Dynamic, 1> numCov((cov.array() != 0.0).matrix().colwise().count()); std::vector<int> candidate; for (int fx=0; fx < numCov.rows(); ++fx) { if (numCov(fx) == 1) candidate.push_back(fx); } if (candidate.size() > 1) { std::vector<bool> mask(numItems()); for (int cx=candidate.size() - 1; cx >= 0; --cx) { std::vector<bool> loading(numItems()); for (int ix=0; ix < numItems(); ++ix) { loading[ix] = param(candidate[cx], itemsMap[ix]) != 0; } std::vector<bool> overlap(loading.size()); std::transform(loading.begin(), loading.end(), mask.begin(), overlap.begin(), std::logical_and<bool>()); if (std::find(overlap.begin(), overlap.end(), true) == overlap.end()) { std::transform(loading.begin(), loading.end(), mask.begin(), mask.begin(), std::logical_or<bool>()); orthogonal.push_back(candidate[cx]); } } } std::reverse(orthogonal.begin(), orthogonal.end()); if (orthogonal.size() == 1) orthogonal.clear(); if (orthogonal.size() && orthogonal[0] != mean.rows() - int(orthogonal.size())) { mxThrow("Independent specific factors must be given after general dense factors"); } numSpecific = orthogonal.size(); if (numSpecific) { Sgroup.assign(numItems(), 0); for (int ix=0; ix < numItems(); ix++) { for (int dx=orthogonal[0]; dx < mean.rows(); ++dx) { if (param(dx, itemsMap[ix]) != 0) { Sgroup[ix] = dx - orthogonal[0]; continue; } } } //Eigen::Map< Eigen::ArrayXi > foo(Sgroup.data(), param.cols()); //mxPrintMat("sgroup", foo); } }
void ifaGroup::detectTwoTier() { int mlen = maxAbilities; if (!twotier || mlen < 3) return; std::vector<int> orthogonal; if (mlen >= 3) { Eigen::Map<Eigen::MatrixXd> Ecov(cov, mlen, mlen); Eigen::Matrix<Eigen::DenseIndex, Eigen::Dynamic, 1> numCov((Ecov.array() != 0.0).matrix().colwise().count()); std::vector<int> candidate; for (int fx=0; fx < numCov.rows(); ++fx) { if (numCov(fx) == 1) candidate.push_back(fx); } if (candidate.size() > 1) { std::vector<bool> mask(numItems()); for (int cx=candidate.size() - 1; cx >= 0; --cx) { std::vector<bool> loading(numItems()); for (int ix=0; ix < numItems(); ++ix) { loading[ix] = param[ix * paramRows + candidate[cx]] != 0; } std::vector<bool> overlap(loading.size()); std::transform(loading.begin(), loading.end(), mask.begin(), overlap.begin(), std::logical_and<bool>()); if (std::find(overlap.begin(), overlap.end(), true) == overlap.end()) { std::transform(loading.begin(), loading.end(), mask.begin(), mask.begin(), std::logical_or<bool>()); orthogonal.push_back(candidate[cx]); } } } std::reverse(orthogonal.begin(), orthogonal.end()); } if (orthogonal.size() == 1) orthogonal.clear(); if (orthogonal.size() && orthogonal[0] != mlen - int(orthogonal.size())) { Rf_error("Independent factors must be given after dense factors"); } numSpecific = orthogonal.size(); if (numSpecific) { Sgroup.assign(numItems(), 0); for (int ix=0; ix < numItems(); ix++) { for (int dx=orthogonal[0]; dx < maxAbilities; ++dx) { if (param[ix * paramRows + dx] != 0) { Sgroup[ix] = dx - orthogonal[0]; continue; } } } } }