4 #include "casm/external/Eigen/CASM_AddOns"
31 throw std::runtime_error(
"Invalid assignment of SymGroupRep. Sizes are incompatible.\n");
46 throw std::runtime_error(std::string(
"SymGroupRep::set_master_group() attempted to assign SymGroupRepID that does not match the current SymGroupRep!\n"));
58 throw std::runtime_error(std::string(
"SymGroupRep::set_master_group() passed new master whose size is incompatible with the size\n") +
59 "of the current representation.\n");
67 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::set_rep(), you are trying to assign the representation of a SymOp whose factor_group is not specified!\n"
84 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::set_rep(), you are trying to assign the representation of a SymOpRepresentation whose factor_group is not specified!\n"
92 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::set_rep(), you are trying to assign the representation of a SymOpRepresentation whose index is not specified!\n"
104 assert(
valid_index(op_index) && op_index <
size() &&
"In SymGroupRep::set_rep(), reference representation is improperly initialized.");
106 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::set_rep(), representation already exists for operation " << op_index <<
".\n"
139 for(
Index i = 0; i < this->
size(); i++) {
143 stream <<
"nullptr\n";
154 stream <<
"SymRep Matrix " << i + 1 <<
" of " <<
size() <<
":\n";
158 stream <<
"nullptr\n";
168 for(
Index i = 0; i < head_group.
size(); i++) {
169 stream <<
"SymRep Matrix " << i + 1 <<
" of " << head_group.
size() <<
":\n";
173 stream <<
"nullptr\n";
199 for(
Index i = 1; i < head_group.
size(); i++) {
216 for(
EigenIndex i = 0; i + 1 < bmat.rows(); i++) {
235 for(
EigenIndex i = 0; i + 1 < bmat.rows(); i++) {
246 throw std::runtime_error(
"SymGroupRep::push_back_copy() only callable on SymGroupRep that has no master\n");
285 std::cerr <<
"CRITICAL ERROR: Trying to perform matrix transformation on a non-matrix SymRep. Exiting...\n";
290 rightmat = Eigen::JacobiSVD<Eigen::MatrixXd>(trans_mat.transpose()).solve(Eigen::MatrixXd::Identity(trans_mat.rows(), trans_mat.rows()));
328 Eigen::FullPivHouseholderQR<Eigen::MatrixXd> QR;
329 QR.setThreshold(
TOL);
332 for(
Index i = 0; i < ssubs.
size(); i++) {
334 tmat.resize(dim, ssubs[i][0].cols()*ssubs[i].
size());
335 for(
Index j = 0; j < ssubs[i].
size(); j++) {
336 tmat.block(0, j * ssubs[i][j].cols(), dim, ssubs[i][j].cols()) = ssubs[i][j];
338 sub_ranks[i] = QR.compute(tmat).rank();
341 Index i_best, n_cols(0);
342 while(n_cols < dim) {
346 for(
Index i = 0; i < ssubs.
size(); i++) {
357 if(ssubs[i][0].cols() < ssubs[i_best][0].cols()
358 || (ssubs[i][0].cols() == ssubs[i_best][0].cols() && sub_ranks[i] < sub_ranks[i_best])
360 || (ssubs[i][0].cols() == ssubs[i_best][0].cols() && sub_ranks[i] == sub_ranks[i_best] && ssubs[i].
size() < ssubs[i_best].
size())) {
367 tmat.resize(dim, n_cols + ssubs[i_best].
size()*ssubs[i_best][0].cols());
368 tmat.leftCols(n_cols) = trans_mat.leftCols(n_cols);
369 for(
EigenIndex k = 0; k < ssubs[i_best][0].cols(); k++) {
370 for(
Index j = 0; j < ssubs[i_best].
size(); j++) {
371 tmat.col(n_cols + k * ssubs[i_best].
size() + j) = ssubs[i_best][j].col(k);
376 n_cols = QR.compute(tmat).rank();
377 trans_mat.leftCols(n_cols) =
Eigen::MatrixXd(tmat.householderQr().householderQ()).leftCols(n_cols);
378 sub_valid[i_best] =
false;
384 for(
Index i = 0; i < ssubs.
size(); i++) {
387 tmat.resize(dim, n_cols + ssubs[i].
size()*ssubs[i][0].cols());
388 tmat.leftCols(n_cols) = trans_mat.leftCols(n_cols);
389 for(
Index j = 0; j < ssubs[i].
size(); j++) {
390 tmat.block(0, n_cols + j * ssubs[i][j].cols(), dim, ssubs[i][j].cols()) = ssubs[i][j];
393 if(QR.compute(tmat).rank() < n_cols + sub_ranks[i]) {
394 sub_valid[i] =
false;
401 return trans_mat.transpose();
422 for(
Index i = 0; i < irrep_IDs.
size(); i++) {
424 Eigen::MatrixXd subtrans_mat = trans_mat.block(irow, 0, irrep.
dim(), trans_mat.cols()).transpose();
425 if(i == 0 || irrep_IDs[i] != irrep_IDs[i - 1]) {
428 for(
Index s = 0; s < irrep_dirs.size(); s++) {
430 sdirs[i].push_back(std::vector<Eigen::VectorXd>());
431 for(
Index d = 0; d < irrep_dirs[s].size(); d++) {
433 sdirs[i].back().push_back(subtrans_mat * irrep_dirs[s][d]);
446 std::vector<Eigen::MatrixXd> wedges(sdirs.size());
447 double best_proj, tproj;
448 multiplicities.clear();
450 for(
Index s = 0; s < sdirs.size(); s++) {
451 wedges[s] = Eigen::MatrixXd::Zero(dim, sdirs[s].
size());
452 wedges[s].col(0) = sdirs[s][0][0];
453 multiplicities.push_back(sdirs[s][0].
size());
454 for(
Index i = 1; i < sdirs[s].size(); i++) {
456 best_proj = (wedges[s].transpose() * sdirs[s][i][0]).
sum();
457 for(
Index j = 1; j < sdirs[s][i].size(); j++) {
458 tproj = (wedges[s].transpose() * sdirs[s][i][j]).
sum();
459 if(tproj > best_proj) {
464 multiplicities.push_back(sdirs[s][i].
size());
465 wedges[s].col(i) = sdirs[s][i][j_best];
473 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::_calc_special_irrep_directions() called on imcompatible SymGroupRep.\n Exiting...\n";
484 Eigen::ColPivHouseholderQR<Eigen::MatrixXd> QR(*(
get_MatrixXd(head_group[0])));
488 QR.setThreshold(10 *
TOL);
492 for(i = 0; i < isubs.size(); i++) {
493 if(isubs[i].
size() == 0 || isubs[i][0].size() == 0) {
494 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::_calc_special_irrep_directions(), attempting to use a zero-size subgroup.\n Exiting...\n";
501 for(j = 0; j < isubs[i][s].size(); j++) {
505 Reynolds /= double(isubs[i][s].
size());
513 QR.compute(Reynolds);
527 for(j = 0; j < sdirs.
size(); j++) {
532 if(j == sdirs.
size()) {
536 for(j = 0; j < head_group.
size(); j++) {
538 if(!sdirs.
back().almost_contains(tdir))
539 sdirs.
back().push_back(tdir);
543 for(j = 0; j < sdirs.
size(); j++) {
548 if(j == sdirs.
size() && dim > 1) {
552 for(j = 0; j < head_group.
size(); j++) {
553 tdir = -(*
get_MatrixXd(head_group[j])) * matrixQ.col(0);
554 if(!sdirs.
back().almost_contains(tdir))
555 sdirs.
back().push_back(tdir);
570 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::calc_special_subspaces() called on imcompatible SymGroupRep.\n Exiting...\n";
583 Eigen::FullPivHouseholderQR<Eigen::MatrixXd> QR(*(
at(0)->
get_MatrixXd()));
585 QR.setThreshold(
TOL);
590 for(i = 0; i < sg_op_inds.size(); i++) {
591 if(sg_op_inds[i].
size() == 0 || sg_op_inds[i][0].size() == 0) {
592 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::calc_special_subspaces(), attempting to use a zero-size subgroup.\n Exiting...\n";
599 for(j = 0; j < sg_op_inds[i][0].size(); j++) {
600 Reynolds += *(
at(head_group[sg_op_inds[i][0][j]].index())->
get_MatrixXd());
603 Reynolds /= double(sg_op_inds[i][0].
size());
606 QR.compute(Reynolds);
614 tsub = QR.matrixQ().leftCols(QR.rank());
618 for(j = 0; j < ssubs.
size(); j++) {
620 if(ssubs[j][0].cols() != tsub.cols())
623 for(k = 0; k < ssubs[j].
size(); k++) {
624 double tdet = (tsub.transpose() * ssubs[j][k]).determinant();
628 if(k < ssubs[j].
size())
636 for(j = 0; j < head_group.
size(); j++) {
638 for(k = 0; k < ssubs.
back().size(); k++) {
639 double tdet = (ttrans.transpose() * ssubs.
back()[k]).determinant();
643 if(k == ssubs.
back().size())
644 ssubs.
back().push_back(ttrans);
654 for(i = 0; i < ssubs.
size(); i++) {
655 for(j = i + 1; j < ssubs.
size(); j++) {
656 if(ssubs[i][0].cols() > ssubs[j][0].cols())
658 if(ssubs[i][0].cols() == ssubs[j][0].cols() && ssubs[i].
size() > ssubs[j].
size())
672 if(tarray.
size() != complex_irrep.size()) {
673 std::cerr <<
"CRITICAL ERROR: Dimension mismatch in SymGroupRep::num_each_real_irrep. Exiting..\n";
679 for(
Index i = 0; i < tarray.
size(); i++) {
680 if(tarray[i] && complex_irrep[i]) {
681 if(i + 1 == tarray.
size() || tarray[i] != tarray[i + 1]) {
682 std::cerr <<
"CRITICAL ERROR: Invalid irrep decomposition found in SymGroupRep::num_each_real_irrep. Exiting..\n";
697 std::cerr <<
"In SymGroupRep::num_each_irrep() attempting to find irrep decomposition of a SymGroupRep that has no valid master_group.\n";
714 std::cout <<
"Decomposing representation:\n ";
715 for(
Index i = 0; i < head_group.
size(); i++) {
721 for(
Index i = 0; i < conj_class.size(); i++) {
722 Index rep_index(head_group[conj_class[i][0]].index());
728 std::cout <<
" Irrep decomposition: ";
729 for(
Index i = 0; i < char_table.size(); i++) {
731 for(
Index j = 0; j < char_table[i].size(); j++) {
732 temp += double(conj_class[j].
size()) * repchar[j] * (char_table[i][j]).real();
734 tdec[i] =
round(temp /
double(head_group.
size()));
736 std::cout <<
" " << tdec[i];
750 for(
Index i = 0; i < irrep_decomp.
size(); i++) {
751 if(irrep_decomp[i] == 0)
758 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::get_irrep_IDs(), cannot resolve irrep " << i <<
" which has multiplicity " << irrep_decomp[i] <<
". Exiting...\n";
774 std::cerr <<
"In SymGroupRep::calc_new_irreps() attempting to calculate new irreps of a SymGroupRep that has no valid master_group.\n";
790 std::cerr <<
"WARNING: In SymGroupRep::calc_new_irreps, size of representation is " <<
size() <<
" and MatrixXd address is " <<
at(0)->
get_MatrixXd() << std::endl
791 <<
" No valid irreps will be returned.\n";
794 if(!head_group.
size()) {
795 assert(0 &&
"In SymGroupRep::calc_new_irreps(), passed an empty SymGroup!");
805 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::calc_new_irreps(), there is no MasterSymGroup available!\n"
811 int Nirrep(i_decomp.
sum());
813 std::cerr <<
"In SymGroupRep::calc_new_irreps(), there are no valid irreps, so no valid irreps will be returned.\n";
826 for(
int i = 0; i < dim; i++) {
827 for(
int j = i; j < dim; j++) {
828 Eigen::MatrixXd tmat(Eigen::MatrixXd::Zero(dim, dim)), tcommute(Eigen::MatrixXd::Zero(dim, dim));
834 for(
Index ns = 0; ns < head_group.
size(); ns++) {
838 for(
Index nc = 0; nc < commuters.
size(); nc++) {
839 double tproj((commuters[nc].array()*tcommute.array()).
sum());
840 tcommute -= tproj * commuters[nc];
842 double tnorm(tcommute.norm());
849 for(
Index nc = 0; nc < commuters.
size(); nc++) {
850 commuters[nc] *= (dim * sqrt(dim));
854 Eigen::JacobiSVD<Eigen::MatrixXd> svd;
856 int Nstep(0), Nfound(0), max_found = 0;
860 while((max_found < Nirrep || min_diff < 0.05 || Nstep < 10) && Nstep < max_iter) {
863 double tmindiff(1e+8), tdiff(0);
867 mags[i] =
ran0(rseed);
870 for(
Index nc = 0; nc < commuters.
size(); nc++) {
871 tmat += mags[nc] * commuters[nc];
873 svd.compute(tmat, Eigen::ComputeFullU);
875 for(
EigenIndex ne = 1; ne < svd.singularValues().size(); ne++) {
876 tdiff = std::abs(svd.singularValues()[ne - 1] - svd.singularValues()[ne]);
879 tmindiff =
std::min(tdiff, tmindiff);
883 if(Nfound > max_found || (Nfound == max_found && tmindiff > min_diff)) {
886 trans_mat = svd.matrixU().transpose();
892 if(Nstep >= max_iter) {
893 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::calc_new_irreps, reached maximum iterations (" << max_iter <<
") without finding all irreps.\n"
894 <<
" I found " << max_found <<
" of " << Nirrep <<
" distinguishable within " << min_diff <<
" (0.1 required). Exiting...\n";
905 for(
Index i = 0; i < head_group.
size(); i++) {
907 tmat = trans_mat * (*(
at(head_group[i].index())->
get_MatrixXd())) * trans_mat.transpose();
909 block_shape.array() += tmat.array() * tmat.array();
915 for(
int i2 = 1; i2 < dim; i2++) {
916 if(block_shape(i2 - 1, i2) > 0.5)
921 tmat.resize(i2 - i1, dim);
922 tmat = trans_mat.block(i1, 0, i2 - i1, dim);
926 if(tdecomp.sum() != 1) {
927 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::calc_new_irreps(), representation identified as irreducible did not pass final tests. Exiting...\n";
931 Index i_irrep = tdecomp.find(1);
951 tmat.resize(dim - i1, dim);
952 tmat = trans_mat.block(i1, 0, dim - i1, dim);
959 if(tdecomp.sum() != 1) {
960 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::calc_new_irreps(), representation identified as irreducible did not pass final tests. Exiting...\n";
964 Index i_irrep = tdecomp.find(1);
1001 for(
Index i = 0; i < head_group.
size(); i++) {
1019 std::vector< std::vector<Index> > subspaces;
1044 tmat(Eigen::MatrixXd::Zero(rep_dim, rep_dim)),
1045 trans_mat(Eigen::MatrixXd::Zero(rep_dim, rep_dim));
1048 Eigen::FullPivLU<Eigen::MatrixXd> LU;
1049 LU.setThreshold(0.001);
1050 Eigen::FullPivHouseholderQR<Eigen::MatrixXd> QR;
1051 QR.setThreshold(0.001);
1054 for(
Index i = 0; i < irrep_decomp.
size(); i++) {
1055 if(irrep_decomp[i] == 0)
1059 if(complex_irrep[i])
1064 int irrep_dim = c_mult *
round(char_table[i][0].real());
1067 assert(irrep_dim == (t_irrep.get_MatrixXd(head_group[0])->rows()));
1072 for(
Index j = 0; j < head_group.
size(); j++) {
1075 tproj += (*(t_irrep.get_MatrixXd(head_group[j])))(0, 0) * (*
get_MatrixXd(head_group[j]));
1077 tproj *= double(irrep_dim) / double(head_group.
size());
1088 tmat = LU.matrixLU().triangularView<Eigen::Upper>();
1094 for(
int j = LU.rank() - 1; j > 0; j--) {
1096 tmat.row(j) /= tval;
1097 for(
int k = 0; k < j; k++) {
1099 tmat.row(k) -= tval * tmat.row(j);
1103 tmat = tmat * LU.permutationQ().inverse();
1109 QR.compute(tmat.transpose());
1110 if(QR.rank() != irrep_decomp[i]) {
1111 std::cerr <<
"CRITICAL ERROR: In SymGroupRep::get_irrep_trans_mat(), did not find correct number of basis vectors to account for\n"
1112 <<
" multiplicity of irrep #" << i <<
". There should be " << irrep_decomp[i] <<
" but I found " << QR.rank() <<
"\n"
1119 subspaces.push_back(std::vector<Index>(irrep_dim));
1120 std::iota(subspaces.back().begin(), subspaces.back().end(), col_count + n * irrep_dim);
1121 trans_mat.col(col_count + n * irrep_dim) = QR.matrixQ().col(n);
1126 for(
int j = 1; j < irrep_dim; j++) {
1129 for(
Index k = 0; k < head_group.
size(); k++) {
1131 tproj += (*(t_irrep.get_MatrixXd(head_group[k])))(j, 0) * (*
get_MatrixXd(head_group[k]));
1133 tproj *= double(irrep_dim) / double(head_group.
size());
1137 tmat = tproj * QR.matrixQ();
1141 trans_mat.col(col_count + n * irrep_dim + j) = tmat.col(n);
1147 col_count += irrep_decomp[i] * irrep_dim;
1150 return trans_mat.transpose();
1160 std::cerr <<
"WARNING: In SymGroupRep::calc_new_irreps, size of representation is " <<
size() <<
" and MatrixXd address is " <<
get_MatrixXd(head_group[0].index()) << std::endl
1161 <<
" No valid irreps will be returned.\n";
1167 std::cout.precision(8);
1168 std::cout.flags(std::ios::showpoint | std::ios::fixed | std::ios::right);
1170 commuters.
push_back(Eigen::MatrixXcd::Identity(dim, dim) / sqrt(
double(dim)));
1171 typedef std::complex<double> cplx;
1176 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXcd> esolve;
1177 Eigen::HouseholderQR<Eigen::MatrixXd> qr;
1178 Eigen::ColPivHouseholderQR<Eigen::MatrixXd> colqr;
1179 colqr.setThreshold(0.001);
1181 Eigen::MatrixXcd tmat(Eigen::MatrixXcd::Zero(dim, dim)), tcommute(Eigen::MatrixXcd::Zero(dim, dim));
1182 Eigen::MatrixXd trans_mat(Eigen::MatrixXd::Zero(dim, dim)), kernel(Eigen::MatrixXd::Random(dim, dim).householderQr().householderQ());
1190 std::cout <<
"~~~~~~~Dimension is " << dim <<
"\n";
1191 for(
Index kci = 0; kci < kernel.cols(); kci++) {
1192 bool found_new_irreps(
false);
1193 for(
Index kcj = kci; kcj < kernel.cols(); kcj++) {
1194 for(
Index nph = 0; nph < 2; nph++) {
1195 if(kci == kcj && nph > 0)
continue;
1200 tmat = phase[nph] * kernel.col(kci) * kernel.col(kcj).transpose()
1201 + std::conj(phase[nph]) * kernel.col(kcj) * kernel.col(kci).transpose();
1204 for(
Index ns = 0; ns < head_group.
size(); ns++) {
1205 tcommute += (*(
get_MatrixXd(head_group[ns].index()))) * tmat * (*(
get_MatrixXd(head_group[ns].index()))).transpose();
1210 for(
Index nc = 0; nc < commuters.
size(); nc++) {
1211 double tproj((commuters[nc].array().conjugate()*tcommute.array()).
sum().real());
1212 tcommute -= tproj * commuters[nc];
1214 double tnorm(tcommute.norm());
1228 esolve.compute(
double(dim)*sqrt(
double(dim))*kernel.transpose()*commuters[nc]*kernel);
1237 tmat = kernel * (esolve.eigenvectors().householderQr().householderQ());
1244 Eigen::MatrixXd block_shape(Eigen::MatrixXd::Zero(kernel.cols(), kernel.cols()));
1246 for(
Index i = 0; i < head_group.
size(); i++) {
1247 trans_rep[head_group[i].index()] = tmat.adjoint() * (*
get_MatrixXd(head_group[i].index())) * tmat;
1248 block_shape += (trans_rep[head_group[i].index()].cwiseProduct(trans_rep[head_group[i].index()].conjugate())).real();
1253 for(
Index ns = 0; ns < subspace_dims.
size(); ns++) {
1257 for(
Index ng = 0; ng < trans_rep.size(); ng++) {
1259 for(
Index i = last_i; i < last_i + subspace_dims[ns]; i++)
1260 tchar += trans_rep[ng](i, i);
1266 std::cout <<
"THE REPRESENTATION IS IRREDUCIBLE!!\n";
1267 std::cout <<
"It's characters are: " << char_array <<
"\n\n";
1270 ttrans_mat.leftCols(subspace_dims[ns]) = sqrt(2.0) * tmat.block(0, last_i, dim, subspace_dims[ns]).real();
1271 ttrans_mat.rightCols(subspace_dims[ns]) = sqrt(2.0) * tmat.block(0, last_i, dim, subspace_dims[ns]).imag();
1276 qr.compute(ttrans_mat);
1279 colqr.compute(ttrans_mat);
1280 Index rnk = colqr.rank();
1281 irrep_dims.
push_back(subspace_dims[ns]);
1282 if(rnk == 2 * subspace_dims[ns])
1283 irrep_dims.
push_back(subspace_dims[ns]);
1290 found_new_irreps =
true;
1293 last_i += subspace_dims[ns];
1295 if(found_new_irreps) {
1296 qr.compute(trans_mat);
1301 if(found_new_irreps) {
1311 for(
Index i = 0; i < head_group.
size(); i++) {
1312 block_shape += (trans_mat.transpose() * (*
get_MatrixXd(head_group[i].index())) * trans_mat).cwiseAbs2();
1314 std::cout <<
"BLOCK MATRIX IS:\n"
1315 << block_shape <<
"\n\n";
1316 std::cout <<
"IRREP DIMENSIONS ARE: " << irrep_dims <<
"\n\n";
1317 return trans_mat.transpose();
1332 for(
Index i = 0; i < conj_class.
size(); i++) {
1333 double dimension = char_table[i][0].real();
1337 tmat += (character * rep_mat);
1356 json[
"symop_representations"].
put_array();
1358 at(i)->
to_json(json[
"symop_representations"]);
1379 for(
Index np = 0; np < permute_rep.
size(); ++np) {
1381 if(perm_ptr == NULL) {
1383 std::cerr <<
"CRITICAL ERROR: In subset_permutation_rep(SymGroupRep,Array<Index>::X2), permute_rep is missing at least one permutation!\n"
1389 for(
Index ns = 0; ns < subsets.
size(); ++ns) {
1390 for(
Index ne = 0; ne < subsets[ns].
size(); ++ne) {
1391 perm_sub[ne] = iperm[subsets[ns][ne]];
1394 for(ns2 = 0; ns2 < subsets.
size(); ++ns2) {
1395 if(perm_sub.
all_in(subsets[ns2])) {
1400 if(ns2 >= subsets.
size()) {
1401 std::cerr <<
"CRITICAL ERROR: In subset_permutation_rep(SymGroupRep,Array<Index>::X2), subsets are not closed under permute_rep permutations!\n"
1421 std::cerr <<
"CRITICAL ERROR: In permuted_direct_sum_rep(SymGroupRep,Array<SymGroupRep const*>), permute_rep does not contain permutations!\n"
1427 for(
Index i = 0; i < sum_reps.
size(); i++) {
1428 if(sum_reps[i] == NULL) {
1433 || sum_reps[i]->get_MatrixXd(0) == NULL) {
1434 std::cerr <<
"CRITICAL ERROR: In permuted_direct_sum_rep(SymGroupRep,Array<SymGroupRep const*>), found incompatible SymGroupReps!\n"
1439 rep_dims[i] = (*sum_reps[i])[0]->get_MatrixXd()->cols();
1447 for(
Index g = 0; g < permute_rep.
size(); g++) {
1450 for(
Index r = 0; r < perm_ptr->
size(); r++) {
1451 if(rep_dims[r] == 0)
continue;
1452 Index new_r = (*perm_ptr)[r];
1453 rep_mat_ptr = sum_reps[new_r]->get_MatrixXd(g);
1454 sum_mat.block(sum_inds[r], sum_inds[new_r], rep_dims[new_r], rep_dims[new_r]) = *rep_mat_ptr;
1464 std::cerr <<
"CRITICAL ERROR: In kron_rep(SymGroupRep,SymGroupRep), taking product of two incompatible SymGroupReps!\n"
1503 resize(json[
"symop_representations"].
size());
1505 for(
int i = 0; i < json[
"symop_representations"].
size(); i++) {
size_type size() const
Returns array size if *this is a JSON array, object size if *this is a JSON object, 1 otherwise.
jsonParser & to_json(jsonParser &json) const
virtual SymOpRepresentation * copy() const =0
Make copy of Derived object through Base-class interface.
ReturnArray< Eigen::MatrixXd > get_projection_operators() const
std::vector< Eigen::MatrixXd > irreducible_wedges(const SymGroup &head_group, std::vector< Index > &multiplicities) const
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
ReturnArray< T > cum_sum(const Array< T > &arr)
virtual Eigen::MatrixXd const * get_MatrixXd() const
void from_json(ClexDescription &desc, const jsonParser &json)
const MasterSymGroup & master_group() const
bool almost_contains(const SymOpRepresentation *&test_elem, double tol_val=TOL) const
Type-safe ID object for communicating and accessing Symmetry representation info. ...
bool empty() const
Returns true if SymGroupRepID has not been initialized with valid group_index or rep_index.
void push_back(const T &toPush)
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
ReturnArray< Index > num_each_irrep() const
SymGroupRep subset_permutation_rep(const SymGroupRep &permute_rep, const Array< Index >::X2 &subsets)
ReturnArray< Array< Eigen::VectorXd > > _calc_special_irrep_directions(const SymGroup &subgroup) const
Index index() const
Index of this operation within the master_group.
Eigen::MatrixXd block_shape_matrix() const
void from_json(const jsonParser &json)
ReturnArray< SymGroupRepID > get_irrep_IDs(const SymGroup &subgroup) const
void set_identifiers(const MasterSymGroup &new_group, SymGroupRepID new_rep_ID)
Change m_master_group and determine op_index.
Eigen::MatrixXd get_irrep_trans_mat(const SymGroup &head_group) const
void print_MatrixXd(std::ostream &stream) const
SymGroupRep kron_rep(const SymGroupRep &LHS, const SymGroupRep &RHS)
SymPermutation describes how a symmetry operation permutes a list of 'things' For example...
virtual double character() const
Calculates character of the representation (if well-defined)
SymGroup is a collection of symmetry operations that satisfy the group property The symmetry operatio...
void calc_new_irreps(int max_iter=1000) const
MasterSymGroup const * m_master_group
Pointer to the home_group that generated this SymGroupRep.
Eigen::MatrixXd::Index EigenIndex
For integer indexing:
bool has_valid_master() const
SymOp is the Coordinate representation of a symmetry operation it keeps fraction (FRAC) and Cartesian...
SymGroupRep const & get_irrep(Index i) const
Get symrep for a particular irrep.
ReturnArray< Array< Eigen::MatrixXd > > calc_special_subspaces(const SymGroup &subgroup) const
typename multivector_impl::multivector_tmp< T, N >::type X
Eigen::MatrixXd const * get_MatrixXd(Index i) const
virtual Permutation const * get_permutation() const
virtual jsonParser & to_json(jsonParser &json) const =0
T norm(const Tensor< T > &ttens)
EigenIndex Index
For long integer indexing:
Permutation inverse() const
Construct permutation that undoes the permutation performed by 'this'.
void print_permutation(std::ostream &stream) const
void set_irrep_ID(Index i, SymGroupRepID ID) const
set symrep ID of a particular irrep
const Array< std::complex< double > >::X2 & character_table() const
const Array< Index >::X3 & subgroups() const
SymOpRepresentation * sum() const
Index dim() const
Matrix dimension of representation.
T min(const T &A, const T &B)
const Array< Index >::X2 & get_conjugacy_classes() const
SymOpRepresentation *& at(Index ind)
SymOpRepresentation is the base class for anything describes a symmetry operation.
SymGroupRepID add_copy_to_master() const
Adds copy of this representation its home_group.
void swap_elem(Index i, Index j)
SymGroupRep & operator=(const SymGroupRep &RHS)
Index find(const T &test_elem) const
SymGroupRepID get_irrep_ID(Index i) const
Get symrep ID of a particular irrep.
void push_back_copy(const SymOpRepresentation &_pushed)
Array & append(const Array &new_tail)
Generalized symmetry matrix representation for arbitrary dimension Can be used to describe applicatio...
bool all_in(const Array &superset) const
ReturnArray< Index > num_each_real_irrep(const SymGroup &subgroup, bool verbose=false) const
const MasterSymGroup & master_group() const
Permutation const * get_permutation(Index i) const
jsonParser & put_obj()
Puts new empty JSON object.
ReturnArray< Index > partition_distinct_values(const Eigen::MatrixBase< Derived > &value, double tol=TOL)
SymGroupRep permuted_direct_sum_rep(const SymGroupRep &permute_rep, const Array< SymGroupRep const * > &sum_reps)
SymGroupRep coord_transformed_copy(const Eigen::MatrixXd &trans_mat) const
Eigen::MatrixXd _symmetrized_irrep_trans_mat(const SymGroup &subgroup) const
SymGroupRep is an alternative representation of a SymGroup for something other than real space...
Index class_of_op(Index i) const
Get conjugacy class index of operation at(i)
multivector< Eigen::VectorXd >::X< 3 > calc_special_total_directions(const SymGroup &subgroup) const
Eigen::MatrixXd get_irrep_trans_mat_blind(const SymGroup &head_group) const
const Array< bool > & get_complex_irrep_list() const
SymGroupRepID m_rep_ID
rep_ID is unique identifier of a specific SymGroupRep instantiation
void set_master_group(const MasterSymGroup &master, const SymGroupRepID &_rep_ID)
SymGroupRepID add_representation(const SymGroupRep &new_rep) const
Add a new representation by passing a reference. SymGroup will store a copy.
Basic std::vector like container (deprecated)
jsonParser & put_array()
Puts new empty JSON array.
bool almost_equal(const GenericCluster< CoordType > &LHS, const GenericCluster< CoordType > &RHS, double tol)
bool valid_index(Index i)
SymGroupRep const & representation(SymGroupRepID i) const
Const access of alternate Representations of a SymGroup.
void set_rep(const SymOpRepresentation &base_rep, const SymOpRepresentation &new_rep) const