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)