3 #include "../interface/common.h" 17 : sort(sort), idx(idx), pos_A(pos_A), pos_B(pos_B), pos_C(pos_C) {}
36 return this->idx == idx;
41 int order_B, T& idx_B,
const int* sym_B)
45 std::vector<index_locator_> indices;
47 for (
int i = 0;i < order_A;i++)
49 int i_in_B;
for (i_in_B = 0;i_in_B < order_B && idx_A[i] != idx_B[i_in_B];i_in_B++);
50 if (i_in_B == order_B)
continue;
55 while (!indices.empty())
57 std::vector<index_locator_> group;
58 group.push_back(indices[0]);
59 group.back().sort = 0;
60 indices.erase(indices.begin());
63 for (std::vector<index_locator_>::iterator
it = indices.begin();;)
65 if (
it == indices.end())
break;
67 if ((group[0].pos_A == -1 &&
it->pos_A != -1) ||
68 (group[0].pos_A != -1 &&
it->pos_A == -1) ||
69 (group[0].pos_B == -1 &&
it->pos_B != -1) ||
70 (group[0].pos_B != -1 &&
it->pos_B == -1))
76 bool sym_in_A =
false;
77 for (
int k = group[0].pos_A-1;k >= 0 && sym_A[k] !=
NS;k--)
79 if (idx_A[k] ==
it->idx)
85 for (
int k = group[0].pos_A+1;k < order_A && sym_A[k-1] !=
NS;k++)
87 if (idx_A[k] ==
it->idx)
99 bool sym_in_B =
false;
100 for (
int k = group[0].pos_B-1;k >= 0 && sym_B[k] !=
NS;k--)
102 if (idx_B[k] ==
it->idx)
108 for (
int k = group[0].pos_B+1;k < order_B && sym_B[k-1] !=
NS;k++)
110 if (idx_B[k] ==
it->idx)
122 group.push_back(*
it);
123 group.back().sort = s++;
124 it = indices.erase(
it);
127 if (group.size() <= 1)
continue;
129 std::vector<int> order_A, order_B;
131 for (
int i = 0;i < (int)group.size();i++)
132 order_A.push_back(group[i].sort);
135 for (
int i = 0;i < (int)group.size();i++)
137 order_B.push_back(group[i].sort);
138 idx_B[group[group[i].sort].pos_B] = group[i].idx;
140 if (sym_B[group[0].pos_B] ==
AS)
156 template <
typename T>
158 int order_B, T& idx_B,
const int* sym_B,
159 int order_C, T& idx_C,
const int* sym_C)
163 std::vector<index_locator_> indices;
165 for (
int i = 0;i < order_A;i++)
167 int i_in_B;
for (i_in_B = 0;i_in_B < order_B && idx_A[i] != idx_B[i_in_B];i_in_B++);
168 if (i_in_B == order_B) i_in_B = -1;
170 int i_in_C;
for (i_in_C = 0;i_in_C < order_C && idx_A[i] != idx_C[i_in_C];i_in_C++);
171 if (i_in_C == order_C) i_in_C = -1;
173 if (i_in_B == -1 && i_in_C == -1)
continue;
175 indices.push_back(
index_locator_(0, idx_A[i], i, i_in_B, i_in_C));
178 for (
int i = 0;i < order_B;i++)
180 int i_in_A;
for (i_in_A = 0;i_in_A < order_A && idx_B[i] != idx_A[i_in_A];i_in_A++);
181 if (i_in_A == order_A) i_in_A = -1;
183 int i_in_C;
for (i_in_C = 0;i_in_C < order_C && idx_B[i] != idx_C[i_in_C];i_in_C++);
184 if (i_in_C == order_C) i_in_C = -1;
186 if (i_in_A != -1 || i_in_C == -1)
continue;
188 indices.push_back(
index_locator_(0, idx_B[i], i_in_A, i, i_in_C));
191 while (!indices.empty())
193 std::vector<index_locator_> group;
194 group.push_back(indices[0]);
195 group.back().sort = 0;
196 indices.erase(indices.begin());
199 for (std::vector<index_locator_>::iterator
it = indices.begin();;)
201 if (
it == indices.end())
break;
203 if ((group[0].pos_A == -1 &&
it->pos_A != -1) ||
204 (group[0].pos_A != -1 &&
it->pos_A == -1) ||
205 (group[0].pos_B == -1 &&
it->pos_B != -1) ||
206 (group[0].pos_B != -1 &&
it->pos_B == -1) ||
207 (group[0].pos_C == -1 &&
it->pos_C != -1) ||
208 (group[0].pos_C != -1 &&
it->pos_C == -1))
214 if (group[0].pos_A != -1)
216 bool sym_in_A =
false;
217 for (
int k = group[0].pos_A-1;k >= 0 && sym_A[k] !=
NS;k--)
219 if (idx_A[k] ==
it->idx)
225 for (
int k = group[0].pos_A+1;k < order_A && sym_A[k-1] !=
NS;k++)
227 if (idx_A[k] ==
it->idx)
240 if (group[0].pos_B != -1)
242 bool sym_in_B =
false;
243 for (
int k = group[0].pos_B-1;k >= 0 && sym_B[k] !=
NS;k--)
245 if (idx_B[k] ==
it->idx)
251 for (
int k = group[0].pos_B+1;k < order_B && sym_B[k-1] !=
NS;k++)
253 if (idx_B[k] ==
it->idx)
266 if (group[0].pos_C != -1)
268 bool sym_in_C =
false;
269 for (
int k = group[0].pos_C-1;k >= 0 && sym_C[k] !=
NS;k--)
271 if (idx_C[k] ==
it->idx)
277 for (
int k = group[0].pos_C+1;k < order_C && sym_C[k-1] !=
NS;k++)
279 if (idx_C[k] ==
it->idx)
292 group.push_back(*
it);
293 group.back().sort = s++;
294 it = indices.erase(
it);
297 if (group.size() <= 1)
continue;
299 std::vector<int> order_A, order_B, order_C;
301 if (group[0].pos_A != -1)
303 for (
int i = 0;i < (int)group.size();i++)
304 order_A.push_back(group[i].sort);
306 if (group[0].pos_B != -1)
309 for (
int i = 0;i < (int)group.size();i++)
311 order_B.push_back(group[i].sort);
312 idx_B[group[group[i].sort].pos_B] = group[i].idx;
314 if (sym_B[group[0].pos_B] ==
AS)
318 if (group[0].pos_C != -1)
321 for (
int i = 0;i < (int)group.size();i++)
323 order_C.push_back(group[i].sort);
324 idx_C[group[group[i].sort].pos_C] = group[i].idx;
326 if (sym_C[group[0].pos_C] ==
AS)
332 for (
int i = 0;i < (int)group.size();i++)
333 order_B.push_back(group[i].sort);
336 for (
int i = 0;i < (int)group.size();i++)
338 order_C.push_back(group[i].sort);
339 idx_C[group[group[i].sort].pos_C] = group[i].idx;
341 if (sym_C[group[0].pos_C] ==
AS)
360 template <
typename T>
362 int order_B,
const T& idx_B,
const int* sym_B,
363 int order_C,
const T& idx_C,
const int* sym_C)
367 for (
int i = 0;i < order_A;i++)
370 for (j = 0;j < order_B && idx_A[i] != idx_B[j];j++);
371 if (j == order_B)
continue;
374 for (k = 0;k < order_C && idx_A[i] != idx_C[k];k++);
375 if (k != order_C)
continue;
378 while (i < order_A &&
382 idx_A[i] == idx_B[j])
390 idx_A[i] != idx_B[j]) ninarow--;
394 for (;ninarow > 1;ninarow--) fact *= ninarow;
401 template <
typename T>
403 int order_B,
const T& idx_B,
const int* sym_B)
409 for (
int i = 0;i < order_A;i++)
413 for (j = 0;j < order_B && idx_A[i] != idx_B[j];j++);
416 while (sym_A[i] !=
NS)
419 for (j = 0;j < order_B && idx_A[i] != idx_B[j];j++);
420 if (j>=order_B) ninarow++;
424 if (sym_A[i-ninarow+1]==
AS)
return 0.0;
425 if (sym_A[i-ninarow+1]==
SY) {
429 if (sym_A[i-ninarow+1]!=
SY)
430 for (;ninarow > 1;ninarow--) fact *= ninarow;
438 int order_B,
int*& idx_B,
const int* sym_B);
441 int order_B,
int*& idx_B,
const int* sym_B,
442 int order_C,
int*& idx_C,
const int* sym_C);
445 int order_B,
int *
const & idx_B,
const int* sym_B,
446 int order_C,
int *
const & idx_C,
const int* sym_C);
449 int order_B,
int *
const & idx_B,
const int* sym_B);
452 template int align_symmetric_indices<std::string>(
int order_A,
std::string& idx_A,
const int* sym_A,
453 int order_B,
std::string& idx_B,
const int* sym_B);
455 template int align_symmetric_indices<std::string>(
int order_A,
std::string& idx_A,
const int* sym_A,
457 int order_C,
std::string& idx_C,
const int* sym_C);
459 template int overcounting_factor<std::string>(
int order_A,
std::string const & idx_A,
const int* sym_A,
460 int order_B,
std::string const & idx_B,
const int* sym_B,
461 int order_C,
std::string const & idx_C,
const int* sym_C);
463 template int overcounting_factor<std::string>(
int order_A,
std::string const & idx_A,
const int* sym_A,
464 int order_B,
std::string const & idx_B,
const int* sym_B);
static bool sortB(const index_locator_ &a, const index_locator_ &b)
static bool sortA(const index_locator_ &a, const index_locator_ &b)
int overcounting_factor(int order_A, const T &idx_A, const int *sym_A, int order_B, const T &idx_B, const int *sym_B, int order_C, const T &idx_C, const int *sym_C)
template int align_symmetric_indices< int * >(int order_A, int *&idx_A, const int *sym_A, int order_B, int *&idx_B, const int *sym_B)
template int overcounting_factor< int * >(int order_A, int *const &idx_A, const int *sym_A, int order_B, int *const &idx_B, const int *sym_B, int order_C, int *const &idx_C, const int *sym_C)
int relativeSign(RAIterator s1b, RAIterator s1e, RAIterator s2b, RAIterator s2e)
static bool sortC(const index_locator_ &a, const index_locator_ &b)
int align_symmetric_indices(int order_A, T &idx_A, const int *sym_A, int order_B, T &idx_B, const int *sym_B)
index_locator_(int sort, int idx, int pos_A, int pos_B, int pos_C)