@@ -26,35 +26,39 @@ std::string ex_to_string(cadabra::Ex::iterator it, const cadabra::Kernel& kernel
2626 return ex_to_string (cadabra::Ex (it), kernel);
2727}
2828
29- std::string adjform_to_string (const cadabra::yr::adjform_t & adjform, const std::vector<cadabra::nset_t ::iterator>& index_map)
29+ std::string adjform_to_string (const cadabra::yr::adjform_t & adjform, const std::vector<cadabra::nset_t ::iterator>* index_map = nullptr )
3030{
3131 std::map<cadabra::yr::index_t , int > dummy_map;
3232 int dummy_counter = 0 ;
3333 std::string res;
3434 for (const auto & elem : adjform) {
35- if (elem < 0 ) {
36- res += *index_map[-(elem + 1 )];
37- }
38- else if (dummy_map.find (elem) != dummy_map.end ()) {
39- res += " d_" + std::to_string (dummy_map[elem]);
35+ if (index_map) {
36+ if (elem < 0 ) {
37+ res += *(*index_map)[-(elem + 1 )];
38+ }
39+ else if (dummy_map.find (elem) != dummy_map.end ()) {
40+ res += " d_" + std::to_string (dummy_map[elem]);
41+ }
42+ else {
43+ dummy_map[adjform[adjform[elem]]] = dummy_counter++;
44+ res += " d_" + std::to_string (dummy_map[adjform[adjform[elem]]]);
45+ }
4046 }
4147 else {
42- dummy_map[adjform[adjform[elem]]] = dummy_counter++;
43- res += " d_" + std::to_string (dummy_map[adjform[adjform[elem]]]);
48+ res += std::to_string (elem);
4449 }
4550 }
4651 return res;
4752}
4853
49- std::string pf_to_string (const cadabra::yr::ProjectedForm& projform, const std::vector<cadabra::nset_t ::iterator>& index_map)
54+ std::string pf_to_string (const cadabra::yr::ProjectedForm& projform, const std::vector<cadabra::nset_t ::iterator>* index_map = nullptr )
5055{
5156 std::stringstream os;
5257 int i = 0 ;
53- int max = 20 ;
58+ int max = std::min ( std::size_t ( 200 ), projform. data . size ()) ;
5459 auto it = projform.data .begin ();
55- while (i < max && i < projform.data .size ()) {
56- for (const auto & elem : it->first )
57- os << elem << ' ' ;
60+ while (i < max) {
61+ os << adjform_to_string (it->first /* , index_map*/ );
5862 os << ' \t ' << it->second << ' \n ' ;
5963 ++i;
6064 ++it;
@@ -65,12 +69,54 @@ std::string pf_to_string (const cadabra::yr::ProjectedForm& projform, const std:
6569 return os.str ();
6670}
6771
68- #define DEBUG_OUTPUT 1
72+ #define DEBUG_OUTPUT 0
6973#define cdebug if (!DEBUG_OUTPUT) {} else std::cerr
7074
7175
7276// //////////////////////////////////////////////////////////////////
7377
78+ // Get the next permutation of adjform and return the number of swaps
79+ // required for the transformation
80+ int next_perm (cadabra::yr::adjform_t & adjform)
81+ {
82+ int n = adjform.size ();
83+
84+ // Find longest non-increasing suffix to get pivot
85+ int pivot = n - 2 ;
86+ while (pivot > -1 ) {
87+ if (adjform[pivot + 1 ] > adjform[pivot])
88+ break ;
89+ --pivot;
90+ }
91+
92+ // Entire sequence is already sorted, return
93+ if (pivot == -1 )
94+ return 0 ;
95+
96+ // Find rightmost element greater than pivot
97+ int idx = n - 1 ;
98+ while (idx > pivot) {
99+ if (adjform[idx] > adjform[pivot])
100+ break ;
101+ --idx;
102+ }
103+
104+ // Swap with pivot
105+ std::swap (adjform[pivot], adjform[idx]);
106+
107+ // Reverse the suffix
108+ int swaps = 1 ;
109+ int maxswaps = (n - pivot - 1 ) / 2 ;
110+ for (int i = 0 ; i < maxswaps; ++i) {
111+ if (adjform[pivot + i + 1 ] != adjform[n - i - 1 ]) {
112+ std::swap (adjform[pivot + i + 1 ], adjform[n - i - 1 ]);
113+ ++swaps;
114+ }
115+ }
116+
117+ return swaps;
118+ }
119+
74120// Returns the position of 'val' between 'begin' and 'end', starting
75121// the search at 'offset'
76122template <typename It, typename T>
@@ -147,19 +193,23 @@ namespace cadabra {
147193 data[adjform] = value;
148194 }
149195
150- void ProjectedForm::apply_young_symmetry (const std::vector< index_t > & indices, bool antisymmetric)
196+ void ProjectedForm::apply_young_symmetry (const adjform_t & indices, bool antisymmetric)
151197 {
152- map_t old_data = data;
198+ map_t old_data;
199+ std::swap (old_data, data);
153200
154201 // Loop over all entries, for each one looping over all permutations
155202 // of the indices to be symmetrized and creating a new term for that
156203 // permutation; then add the new term to the list of entries
157204 for (const auto & kv : old_data) {
205+
206+ cdebug << " Applying young_symmetry " << (antisymmetric ? -kv.second : kv.second ) << " * " << adjform_to_string (indices) << " to term " << adjform_to_string (kv.first ) << ' \n ' ;
207+
158208 auto perm = indices;
159- bool flip = false ;
160209 int parity = 1 ;
161- while (std::next_permutation (perm.begin (), perm.end ())) {
162- if (antisymmetric && (flip = !flip))
210+ int swaps = 2 ;
211+ do {
212+ if (antisymmetric && swaps % 2 != 0 )
163213 parity *= -1 ;
164214 auto ret = kv.first ;
165215 for (size_t i = 0 ; i < indices.size (); ++i) {
@@ -169,8 +219,9 @@ namespace cadabra {
169219 if (ret[index] >= 0 )
170220 ret[ret[index]] = index;
171221 }
222+ cdebug << " \t Made term " << adjform_to_string (ret) << " * " << (parity * kv.second ) << ' \n ' ;
172223 data[ret] += parity * kv.second ;
173- }
224+ } while (swaps = next_perm (perm));
174225 }
175226 }
176227
@@ -539,7 +590,7 @@ ProjectedForm young_reduce::symmetrize(Ex::iterator it)
539590
540591 sym.multiply (*it->multiplier );
541592
542- cdebug << sym << ' \n ' ;
593+ cdebug << pf_to_string ( sym, &index_map) << ' \n ' ;
543594
544595 return sym;
545596}
0 commit comments