10 namespace SymRepTools_v2 {
41 Eigen::MatrixXcd
const &irrep_subspace,
double vec_compare_tol,
44 auto const &sgroups = (use_all_subgroups ? all_subgroups : cyclic_subgroups);
46 std::vector<Eigen::VectorXcd> tdirs;
48 Index dim = rep[0].rows();
52 for (
auto const &orbit : sgroups) {
56 for (
Index element_index : *(orbit.begin())) {
57 R += rep[element_index];
60 if ((R * irrep_subspace).norm() <
TOL)
continue;
64 auto QR = (R * irrep_subspace).colPivHouseholderQr();
67 if (QR.rank() > 1)
continue;
68 Eigen::MatrixXcd Q = QR.matrixQ();
71 tdirs.push_back(Q.col(0));
72 tdirs.push_back(-Q.col(0));
81 std::set<SimpleOrbit<VectorSymCompare>> orbit_result;
82 for (Eigen::VectorXcd
const &direction : tdirs) {
83 orbit_result.emplace(direction, head_group.begin(), head_group.end(),
87 for (
auto const &orbit : orbit_result) {
88 result.emplace_back(orbit.begin(), orbit.end());
91 if (use_all_subgroups || result.size() >= irrep_subspace.cols()) {
95 vec_compare_tol, cyclic_subgroups,
103 Eigen::MatrixXcd
const &irrep_subspace,
double vec_compare_tol) {
110 Eigen::MatrixXcd result;
111 Index dim = irrep_subspace.cols();
112 Index min_mult = 10000;
113 bool orb_orthog =
false;
114 bool tot_orthog =
false;
116 Eigen::MatrixXcd axes, orb_axes, tot_axes;
118 tot_axes.setZero(irrep_subspace.rows(), dim);
120 for (
auto const &orbit : irrep_special_directions) {
122 if ((orb_orthog && orbit.size() < min_mult) || !orb_orthog) {
123 orb_axes.setZero(irrep_subspace.rows(), dim);
125 for (
auto const &el : orbit) {
126 if (
almost_zero((el.adjoint() * orb_axes).eval(), vec_compare_tol)) {
127 if (col < orb_axes.cols())
128 orb_axes.col(col++) = el;
130 std::stringstream errstr;
132 <<
"Error in irrep_symmtrizer_from_directions(). Constructing "
133 "coordinate axes from special directions of space spanned "
135 << irrep_subspace.transpose()
136 <<
"\nAxes collected thus far are the row vectors:\n"
137 << orb_axes.transpose()
138 <<
"\nBut an additional orthogonal row vector has been found:\n"
140 <<
"\nindicating that irrep_subspace matrix is malformed.";
141 throw std::runtime_error(errstr.str());
151 min_mult = orbit.size();
158 if (!orb_orthog && !tot_orthog) {
159 for (
auto const &el : orbit) {
160 if (
almost_zero((el.adjoint() * tot_axes).eval(), vec_compare_tol)) {
161 if (tot_col < tot_axes.cols())
162 tot_axes.col(tot_col++) = el;
164 std::stringstream errstr;
166 <<
"Error in irrep_symmtrizer_from_directions(). Constructing "
167 "coordinate axes from special directions of space spanned "
169 << irrep_subspace.transpose()
170 <<
"\nAxes collected thus far are the row vectors:\n"
171 << tot_axes.transpose()
172 <<
"\nBut an additional orthogonal row vector has been found:\n"
174 <<
"\nindicating that irrep_subspace matrix is malformed.";
175 throw std::runtime_error(errstr.str());
179 if (tot_col == dim) {
190 if (!orb_orthog && !tot_orthog && orbit.size() < min_mult) {
191 orb_axes.setZero(irrep_subspace.rows(), orbit.size());
192 for (
Index col = 0; col < orbit.size(); ++col) {
193 orb_axes.col(col) = orbit[col];
197 min_mult = orbit.size();
198 axes = Eigen::MatrixXcd(orb_axes.colPivHouseholderQr().matrixQ())
204 if (axes.cols() == 0) {
205 result = irrep_subspace.colPivHouseholderQr().solve(
209 result = irrep_subspace.colPivHouseholderQr().solve(axes);
bool almost_zero(const T &val, double tol=TOL)
If T is not integral, use std::abs(val) < tol;.
INDEX_TYPE Index
For long integer indexing:
Shortcut for multidimensional vector (std::vector< std::vector< ...)
typename multivector_impl::multivector_tmp< T, N >::type X