00001 #ifndef _EXP_CLASSES_H_
00002 #define _EXP_CLASSES_H_
00003
00004 #include "my_gmp.H"
00005 #include <sstream>
00006 #include <string>
00007 #include "algebras.H"
00008 #include "tables.H"
00009 #include "repring.H"
00010 using namespace std;
00011
00013
00023 template <class K>
00024 class Exponentiator {
00025 public:
00026
00027
00029 RepresentationRing *source;
00031 GradedAlgebra<K> *target;
00032
00033
00034
00036
00042 long last_actual_variable;
00044
00048 long max_dim;
00050
00060 long max_dim_rel;
00062
00067 Table< Polynomial<K> > var;
00069
00088 Tuple< Polynomial<K> > a, b, s, sp;
00089
00090
00092
00100 list< pair< Polynomial<QQ>, Polynomial<QQ> > > equations;
00102 list< Polynomial<K> > total_relations;
00104 list< Polynomial<K> > exp_relations;
00105
00106
00108 long factor;
00109
00111
00121 map< pair<long, long> , Polynomial<K> > univ_computed;
00123 map< pair<long, long> , Polynomial<K> > lambda_univ_computed;
00124
00125
00126
00127
00128
00129 virtual ~Exponentiator<K>(){}
00130
00131
00132
00133
00134
00136
00142 virtual void create_regular_variables(string prefix){
00143 long i, j, dim;
00144 QQ d;
00145 ostringstream autoname;
00146
00147
00148
00149 dim= 0;
00150 for(i=1; i <= source->variables_in_use(); i++){
00151 d= source->epsilon[i];
00152 if( d > dim)
00153 dim= ZZtolong(d);
00154 }
00155
00156 max_dim= dim;
00157 var.resize(source->variables_in_use() +1, dim+1);
00158
00159
00160 for(i=1; i <= source->variables_in_use(); i++){
00161
00162 dim= ZZtolong( source->epsilon[i] );
00163 for(j=1; j<= dim; j++){
00164
00165 autoname.str("");
00166 autoname << prefix << "_" << j
00167 << "(" << source->nameof(i) << ")";
00168 var(i,j)= target->new_variable(autoname.str(), factor*j);
00169 }
00170 }
00171
00172 }
00173
00175
00188 void create_extra_variables(string prefix){
00189 long i;
00190 ostringstream autoname;
00191
00192 last_actual_variable= target->variables_in_use();
00193
00194 a.resize(max_dim+1);
00195 for(i=1; i<= max_dim; i++){
00196 autoname.str("");
00197 autoname << "a_" << i;
00198 a[i]= target->new_variable(autoname.str(), 1);
00199 }
00200
00201 b.resize(max_dim_rel+1);
00202 for(i=1; i<= max_dim_rel; i++){
00203 autoname.str("");
00204 autoname << "b_" << i;
00205 b[i]= target->new_variable(autoname.str(), 1);
00206 }
00207
00208 s.resize(max_dim+1);
00209 for(i=1; i<= max_dim; i++){
00210 autoname.str("");
00211 autoname << prefix << "_" << i;
00212 s[i]= target->new_variable(autoname.str(), i);
00213 }
00214
00215 sp.resize(max_dim_rel+1);
00216 for(i=1; i<= max_dim_rel; i++){
00217 autoname.str("");
00218 autoname << prefix << "'_" << i;
00219 sp[i]= target->new_variable(autoname.str(), i);
00220 }
00221 }
00222
00224 void kill_extra_variables(){
00225 long i,n;
00226 Polynomial<K> zero_poly;
00227
00228 n= target->variables_in_use() - last_actual_variable;
00229 for(i=1; i<= n;i++)
00230 target->kill_top_variable(zero_poly);
00231 }
00232
00233
00234
00235
00237
00249 void clean_up_equations(){
00250 Polynomial<QQ> left, right;
00251 Polynomial<QQ> temp, dummy;;
00252 QQ num, den;
00253 ZZ thegcd;
00254 long d, max_dim_pow;
00255 typename list< Polynomial<QQ> >::iterator it;
00256 typename map< PowProd, QQ >::iterator pow_it;
00257
00258 left.alphabet= source;
00259 right.alphabet= source;
00260 max_dim_pow= 0;
00261
00262 for(it= source->relations.generators.begin();
00263 it != source->relations.generators.end();
00264 it++){
00265 temp= *it;
00266 thegcd= 0;
00267 for(pow_it= temp.coeffs.begin();
00268 pow_it != temp.coeffs.end();
00269 pow_it ++){
00270
00271 dummy= Polynomial<QQ>(pow_it->first);
00272 d= ZZtolong(dummy.evaluate(source->epsilon));
00273 if(d > max_dim_pow)
00274 max_dim_pow= d;
00275
00276
00277 num= pow_it->second.get_num();
00278 den= pow_it->second.get_den();
00279 temp *= den;
00280
00281 thegcd= gcd(thegcd, num);
00282
00283 if(num > 0)
00284 left.add_term(pow_it->first, num);
00285 else
00286 right.add_term(pow_it->first, -num);
00287 }
00288
00289 left*= 1/QQ(thegcd);
00290 right*= 1/QQ(thegcd);
00291
00292 equations.push_back( make_pair( left, right ) );
00293 left.sets_to_zero();
00294 right.sets_to_zero();
00295 }
00296 max_dim_rel= max_dim_pow;
00297 }
00298
00299
00300
00301
00302
00303
00305
00322 Polynomial<K> compute_tensor_relation(long max_dim1, long max_dim2){
00323 long i, j, deg;
00324 Polynomial<K> P, Q, I, debug;
00325 Tuple< Polynomial<K> > sigma, sigmap;
00326 PowProd pow;
00327 Polynomial<K> ans;
00328
00329 I= target->one();
00330
00331
00332
00333 sigma.resize(max_dim1 + 1);
00334 sigmap.resize(max_dim2 + 1);
00335 P= I;
00336 Q= I;
00337 debug= I;
00338 for(i=1; i<=max_dim1; i++){
00339 P*= I + a[i];
00340 }
00341 for(i=1; i<=max_dim2; i++){
00342 Q*= I + b[i];
00343 }
00344
00345 for(i=1; i<=max_dim1; i++){
00346 sigma[i]= target->hom_part_of(P,i);
00347 }
00348 for(i=1; i<=max_dim2; i++){
00349 sigmap[i]= target->hom_part_of(Q,i);
00350 }
00351
00352
00353
00354
00355 P= I;
00356
00357 for(i=1; i<=max_dim1; i++)
00358 for(j=1; j<=max_dim2; j++)
00359 P*= I + a[i] + b[j];
00360
00361
00362
00363 ans=I;
00364 ans.sets_to_zero();
00365
00366
00367 while( !P.is_zero() ){
00368
00369
00370 pow= P.lp();
00371
00372
00373
00374 Q= I;
00375 debug= I;
00376 for(i=1; i<=max_dim1; i++){
00377 deg= pow.power_of(last_actual_variable + max_dim1 + 1 - i);
00378 if(i != max_dim1)
00379 deg-= pow.power_of(last_actual_variable + max_dim1 - i);
00380
00381 for(j=1; j<= deg; j++){
00382 Q *= sigma[i];
00383 debug *= s[i];
00384 }
00385 }
00386
00387 for(i=1; i<=max_dim2; i++){
00388 deg= pow.power_of(last_actual_variable + max_dim + max_dim2 + 1 - i);
00389 if(i != max_dim2)
00390 deg-= pow.power_of(last_actual_variable + max_dim + max_dim2 - i);
00391
00392 for(j=1; j<= deg; j++){
00393 Q *= sigmap[i];
00394 debug *= sp[i];
00395 }
00396 }
00397
00398
00399
00400
00401 ans+= debug*P.coeff_of(pow);
00402 P+= Q*(-1)*P.coeff_of(pow);
00403 }
00404
00405 return ans;
00406
00407 }
00409
00416 void write_lambda_factors(list< Polynomial<K> >& result, long ext, long first, long last){
00417 list< Polynomial<K> > temp1, temp2;
00418 typename list< Polynomial<K> >::iterator it;
00419
00420
00421
00422 if( (ext < 1) ){
00423 result.clear();
00424 result.push_front( target->one() );
00425 return;
00426 }
00427
00428 if( (ext > last - first + 1) ){
00429 result.clear();
00430 return;
00431 }
00432
00433
00434
00435 write_lambda_factors(result, ext, first + 1, last);
00436 write_lambda_factors(temp2, ext - 1, first + 1, last);
00437
00438
00439 for(it= temp2.begin(); it != temp2.end(); it++)
00440 result.push_back( *it + a[ first ] );
00441 return;
00442
00443 }
00445
00448 Polynomial<K> compute_lambda_relation(long ext, long dim){
00449 long i, j, deg;
00450 Polynomial<K> P, Q, I, debug;
00451 Tuple< Polynomial<K> > sigma;
00452 PowProd pow;
00453 Polynomial<K> ans;
00454 list< Polynomial<K> > splits;
00455 typename list< Polynomial<K> >::iterator it;
00456
00457 I= target->one();
00458
00459
00460
00461 sigma.resize(dim + 1);
00462 P= I;
00463
00464 for(i=1; i<=dim; i++){
00465 P*= I + a[i];
00466 }
00467
00468 for(i=1; i<= dim; i++){
00469 sigma[i]= target->hom_part_of(P,i);
00470 }
00471
00472
00473
00474
00475
00476 write_lambda_factors(splits, ext, 1, dim);
00477
00478
00479 for(P= I, it= splits.begin(); it != splits.end(); it++)
00480 P*= *it;
00481
00482
00483
00484 ans=I;
00485 ans.sets_to_zero();
00486
00487
00488 while( !P.is_zero() ){
00489
00490
00491 pow= P.lp();
00492
00493
00494
00495 Q= I;
00496 debug= I;
00497 for(i=1; i<=dim; i++){
00498 deg= pow.power_of(last_actual_variable + dim + 1 - i);
00499 if(i != dim)
00500 deg-= pow.power_of(last_actual_variable + dim - i);
00501
00502 for(j=1; j<= deg; j++){
00503 Q *= sigma[i];
00504 debug *= s[i];
00505 }
00506 }
00507
00508 ans+= debug*P.coeff_of(pow);
00509 P+= Q*(-1)*P.coeff_of(pow);
00510 }
00511
00512 return ans;
00513 }
00514
00515
00516
00518
00540 void exp_classes_after_tensoring(const Polynomial<K>& exp,
00541 long dim,
00542 const PowProd& pow,
00543 Polynomial<K>& result) {
00544
00545 long i, j, d;
00546 PowProd new_pow;
00547 Polynomial<K> universal;
00548
00549
00550 if(pow == PowProd(0)){
00551 result= exp;
00552 return;
00553 }
00554
00555
00556
00557 for(i=1; i<= pow.nvars(); i++)
00558 if( pow.power_of(i) > 0 )
00559 break;
00560 d= ZZtolong(source->epsilon[i]);
00561
00562
00563 if( univ_computed.count( make_pair(d,dim) )==0 )
00564 univ_computed[ make_pair(d,dim) ] = compute_tensor_relation(d, dim);
00565
00566 universal= univ_computed[ make_pair(d,dim) ] ;
00567
00568
00569 for(j=1; j<= d; j++)
00570 universal.substitute_variable(last_actual_variable + max_dim
00571 + max_dim_rel +j, var(i,j) );
00572
00573 for(j=1; j<= dim; j++)
00574 universal.substitute_variable(last_actual_variable + 2*max_dim
00575 + max_dim_rel + j,
00576 target->hom_part_of(exp,j*factor));
00577
00578
00579
00580
00581 new_pow= pow/PowProd(i);
00582 exp_classes_after_tensoring(universal, d*dim, new_pow, result);
00583 return;
00584 }
00585
00587
00599 Polynomial<K> exp_classes_of_ext_power(long thevar, long ext){
00600 long dim, j;
00601 Polynomial<K> universal;
00602
00603 dim= ZZtolong(source->epsilon[thevar]);
00604
00605
00606
00607 if( lambda_univ_computed.count( make_pair(ext,dim) )==0 )
00608 lambda_univ_computed[ make_pair(ext,dim) ] = compute_lambda_relation(ext, dim);
00609
00610 universal= lambda_univ_computed[ make_pair(ext,dim) ] ;
00611
00612
00613 for(j=1; j<= dim; j++)
00614 universal.substitute_variable(last_actual_variable + max_dim
00615 + max_dim_rel +j, var(thevar,j) );
00616 return universal;
00617 }
00618
00620
00635 void compute_exp_relations(){
00636 Polynomial<K> templeft, tempright, P, Q;
00637 long i, j, k, n;
00638 typename list< pair< Polynomial<QQ>, Polynomial<QQ> > >::iterator it;
00639 typename map< PowProd, QQ>::iterator it_pow;
00640
00642
00643
00644 if(target->verbose)
00645 cout << endl
00646 <<"{\\bf Translating the relations}"
00647 << endl << endl;
00648
00649 for(it= equations.begin(); it!= equations.end(); it++){
00650
00651 if(target->very_verbose)
00652 cout << "we examine equation $" << it->first
00653 << " = " << it->second
00654 << "$" << endl << endl;
00655
00656 templeft= target->one();
00657 tempright= target->one();
00658
00659 for(it_pow= it->first.coeffs.begin();
00660 it_pow!= it->first.coeffs.end();
00661 it_pow++){
00662
00663 exp_classes_after_tensoring(target->one(), 1, it_pow->first, P);
00664
00665 n= ZZtolong(it_pow->second);
00666 Q= P;
00667 for(i=2; i<= n; i++)
00668 P*= Q;
00669
00670 templeft*= P;
00671 }
00672
00673 for(it_pow= it->second.coeffs.begin();
00674 it_pow!= it->second.coeffs.end();
00675 it_pow++){
00676
00677 exp_classes_after_tensoring(target->one(), 1, it_pow->first, P);
00678
00679 n= ZZtolong(it_pow->second);
00680 Q= P;
00681 for(i=2; i<= n; i++)
00682 P*= Q;
00683
00684 tempright*= P;
00685 }
00686
00687 templeft+= tempright*(-1);
00688 total_relations.push_back(templeft);
00689
00690 if(target->very_verbose)
00691 cout << "translated into $" << templeft
00692 << " = 0" << "$" << endl << endl;
00693
00694 }
00695
00697
00698
00699 for(i= 1; i <= source->variables_in_use(); i++)
00700 for(j= 2; j <= source->epsilon[i]; j++){
00701
00702 if(target->very_verbose)
00703 cout << "we examine equation $\\lambda^" << j
00704 << "(" << source->nameof(i) << ") = "
00705 << source->lambda_operations[i][j]
00706 << "$" << endl << endl;
00707
00708
00709 templeft= exp_classes_of_ext_power(i, j);
00710 tempright= target->one();
00711
00712
00713 for(it_pow= source->lambda_operations[i][j].coeffs.begin();
00714 it_pow != source->lambda_operations[i][j].coeffs.end();
00715 it_pow++){
00716 exp_classes_after_tensoring(target->one(), 1, it_pow->first, P);
00717 n= ZZtolong( it_pow->second );
00718 if( n < 0 )
00719 for(k=1; k <= -n; k++)
00720 templeft*= P;
00721 else
00722 for(k=1; k <= n; k++)
00723 tempright*= P;
00724 }
00725
00726 templeft+= tempright*(-1);
00727 total_relations.push_back(templeft);
00728
00729 if(target->very_verbose)
00730 cout << "translated into $" << templeft
00731 << " = 0$" << endl << endl;
00732 }
00733
00734
00735
00736 }
00737
00738 void split_and_sort(){
00739 long i;
00740 Polynomial<K> P;
00741 typename list< Polynomial<K> >::iterator total_it;
00742
00744
00745
00746
00747
00748 if(target->verbose)
00749 cout << endl
00750 << "{\\bf Now splitting into homogeneous parts}"
00751 << endl << endl;
00752
00753
00754
00755 i= 0;
00756 while( !total_relations.empty() ){
00757 i++;
00758
00759 if(target->very_verbose)
00760 cout << "adding the relations in degree " << i
00761 << endl << endl;
00762
00763 for(total_it= total_relations.begin();
00764 total_it != total_relations.end();){
00765 P= target->hom_part_of(*total_it, i);
00766 if( !P.is_zero() ){
00767 if( target->very_verbose)
00768 cout << "adding $" << P << " = 0$"
00769 << endl << endl;
00770 exp_relations.push_back(P);
00771 *total_it += P*(-1);
00772 }
00773 if( total_it->is_zero() )
00774 total_it= total_relations.erase(total_it);
00775 else
00776 total_it++;
00777 }
00778 }
00779
00780
00781
00782 }
00783
00784
00786
00791 void add_relations(){
00792
00793 target->relations.generators= exp_relations;
00794 exp_relations.clear();
00795 total_relations.clear();
00796 }
00797
00799
00841 void start(RepresentationRing *thesource,
00842 GradedAlgebra<K> *thetarget,
00843 string prefix,
00844 long thefactor){
00845
00846 source= thesource;
00847 target= thetarget;
00848 factor= thefactor;
00849
00850 this->create_regular_variables(prefix);
00851 this->clean_up_equations();
00852 this->create_extra_variables(prefix);
00853 this->compute_exp_relations();
00854 this->split_and_sort();
00855 this->kill_extra_variables();
00856 this->add_relations();
00857 }
00858
00859 };
00860
00861
00862 #endif
00863
00864
00865
00866
00867
00868