GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
/*1* Normaliz2* Copyright (C) 2007-2014 Winfried Bruns, Bogdan Ichim, Christof Soeger3* This program is free software: you can redistribute it and/or modify4* it under the terms of the GNU General Public License as published by5* the Free Software Foundation, either version 3 of the License, or6* (at your option) any later version.7*8* This program is distributed in the hope that it will be useful,9* but WITHOUT ANY WARRANTY; without even the implied warranty of10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11* GNU General Public License for more details.12*13* You should have received a copy of the GNU General Public License14* along with this program. If not, see <http://www.gnu.org/licenses/>.15*16* As an exception, when this program is distributed through (i) the App Store17* by Apple Inc.; (ii) the Mac App Store by Apple Inc.; or (iii) Google Play18* by Google Inc., then that store may impose any digital rights management,19* device limits and/or redistribution restrictions that are required by its20* terms of service.21*/2223#ifdef NMZ_MIC_OFFLOAD24#pragma offload_attribute (push, target(mic))25#endif2627#include "libnormaliz/cone_helper.h"28#include "libnormaliz/vector_operations.h"29#include "libnormaliz/my_omp.h"3031namespace libnormaliz {32using std::vector;3334//---------------------------------------------------------------------------3536// determines the maximal subsets in a vector of subsets given by their indicator vectors37// result returned in is_max_subset -- must be initialized outside38// only set to false in this routine39// if a set occurs more than once, only the last instance is recognized as maximal40void maximal_subsets(const vector<vector<bool> >& ind, vector<bool>& is_max_subset) {4142if(ind.size()==0)43return;4445size_t nr_sets=ind.size();46size_t card=ind[0].size();47vector<key_t> elem(card);4849for (size_t i = 0; i <nr_sets; i++) {50if(!is_max_subset[i]) // already known to be non-maximal51continue;5253size_t k=0; // counts the number of elements in set with index i54for (size_t j = 0; j <card; j++) {55if (ind[i][j]) {56elem[k]=j;57k++;58}59}6061for (size_t j = 0; j <nr_sets; j++) {62if (i==j || !is_max_subset[j] ) // don't compare with itself or something known not to be maximal63continue;64size_t t;65for (t = 0; t<k; t++) {66if (!ind[j][elem[t]])67break; // not a superset68}69if (t==k) { // found a superset70is_max_subset[i]=false;71break; // the loop over j72}73}74}75}7677//---------------------------------------------------------------------------78// computes c1*v1-c2*v279template<typename Integer>80vector<Integer> FM_comb(Integer c1, const vector<Integer>& v1,Integer c2, const vector<Integer>& v2, bool& is_zero){8182size_t dim=v1.size();83vector<Integer> new_supp(dim);84is_zero=false;85size_t k=0;86for(;k<dim;++k){87new_supp[k]=c1*v1[k]-c2*v2[k];88if(!check_range(new_supp[k]))89break;90}91Integer g=0;92if(k==dim)93g=v_make_prime(new_supp);94else{ // redo in GMP if necessary95#pragma omp atomic96GMP_hyp++;97vector<mpz_class> mpz_neg(dim), mpz_pos(dim), mpz_sum(dim);98convert(mpz_neg, v1);99convert(mpz_pos, v2);100for (k = 0; k <dim; k++)101mpz_sum[k]=convertTo<mpz_class>(c1)*mpz_neg[k]-102convertTo<mpz_class>(c2)*mpz_pos[k];103mpz_class GG=v_make_prime(mpz_sum);104convert(new_supp, mpz_sum);105convert(g,GG);106}107if(g==0)108is_zero=true;109return new_supp;110}111112template<typename IntegerPL, typename IntegerRet>113vector<size_t> ProjectAndLift<IntegerPL,IntegerRet>::order_supps(const Matrix<IntegerPL>& Supps){114115assert(Supps.nr_of_rows()>0);116size_t dim=Supps.nr_of_columns();117118vector<pair<IntegerPL,size_t> > NewPos,NewNeg; // to record the order of the support haperplanes119for(size_t i=0;i<Supps.nr_of_rows();++i){120if(Supps[i][dim-1] >= 0)121NewPos.push_back(make_pair(-Supps[i][dim-1],i));122else123NewNeg.push_back(make_pair(Supps[i][dim-1],i));124}125sort(NewPos.begin(),NewPos.end());126sort(NewNeg.begin(),NewNeg.end());127128size_t min_length=NewNeg.size();129if(NewPos.size()<min_length)130min_length=NewPos.size();131132vector<size_t> Order;133134for(size_t i=0;i<min_length;++i){135Order.push_back(NewPos[i].second);136Order.push_back(NewNeg[i].second);137}138for(size_t i=min_length;i<NewPos.size();++i)139Order.push_back(NewPos[i].second);140for(size_t i=min_length;i<NewNeg.size();++i)141Order.push_back(NewNeg[i].second);142143assert(Order.size()==Supps.nr_of_rows());144145/* for(size_t i=0;i<Order.size();++i)146cout << Supps[Order[i]][dim-1] << " ";147cout << endl;*/148149return Order;150}151//---------------------------------------------------------------------------152template<typename IntegerPL, typename IntegerRet>153void ProjectAndLift<IntegerPL,IntegerRet>::compute_projections(size_t dim, vector< boost::dynamic_bitset<> >& Ind,154vector< boost::dynamic_bitset<> >& Pair, vector< boost::dynamic_bitset<> >& ParaInPair,155size_t rank){156157INTERRUPT_COMPUTATION_BY_EXCEPTION158159if(dim==1)160return;161162const Matrix<IntegerPL> & Supps=AllSupps[dim];163size_t dim1=dim-1;164165if(verbose)166verboseOutput() << "embdim " << dim << " inequalities " << Supps.nr_of_rows() << endl;167168// cout << "SSS" << Ind.size() << " " << Ind;169170// We now augment the given cone by the last basis vector and its negative171// Afterwards we project modulo the subspace spanned by them172173vector<key_t> Neg, Pos; // for the Fourier-Motzkin elimination of inequalities174Matrix<IntegerPL> SuppsProj(0,dim); // for the support hyperplanes of the projection175Matrix<IntegerPL> EqusProj(0,dim); // for the equations (both later minimized)176177// First we make incidence vectors with the given generators178vector< boost::dynamic_bitset<> > NewInd; // for the incidence vectors of the new hyperplanes179vector< boost::dynamic_bitset<> > NewPair; // for the incidence vectors of the new hyperplanes180vector< boost::dynamic_bitset<> > NewParaInPair; // for the incidence vectors of the new hyperplanes181182boost::dynamic_bitset<> TRUE;183if(!is_parallelotope){184TRUE.resize(Ind[0].size());185TRUE.set();186}187188vector<bool> IsEquation(Supps.nr_of_rows());189190bool rank_goes_up=false; // if we add the last unit vector191size_t PosEquAt=0; // we memorize the positions of pos/neg equations if rank goes up192size_t NegEquAt=0;193194for(size_t i=0;i<Supps.nr_of_rows();++i){195if(!is_parallelotope && Ind[i]==TRUE)196IsEquation[i]=true;197198if(Supps[i][dim1]==0){ // already independent of last coordinate199no_crunch=false;200if(IsEquation[i])201EqusProj.append(Supps[i]); // is equation202else{203SuppsProj.append(Supps[i]); // neutral support hyperplane204if(!is_parallelotope)205NewInd.push_back(Ind[i]);206else{207NewPair.push_back(Pair[i]);208NewParaInPair.push_back(ParaInPair[i]);209}210}211continue;212}213if(IsEquation[i])214rank_goes_up=true;215if(Supps[i][dim1]>0){216if(IsEquation[i])217PosEquAt=i;218Pos.push_back(i);219continue;220}221Neg.push_back(i);222if(IsEquation[i])223NegEquAt=i;224}225226// cout << "Nach Pos/Neg " << EqusProj.nr_of_rows() << " " << Pos.size() << " " << Neg.size() << endl;227228// now the elimination, matching Pos and Neg229230// cout << "rank_goes_up " << rank_goes_up << endl;231232bool skip_remaining;233#ifndef NCATCH234std::exception_ptr tmp_exception;235#endif236237if(rank_goes_up){238239assert(!is_parallelotope);240241for(size_t i=0;i<Pos.size();++i){ // match pos and neg equations242size_t p=Pos[i];243if(!IsEquation[p])244continue;245IntegerPL PosVal=Supps[p][dim1];246for(size_t j=0;j<Neg.size();++j){247size_t n=Neg[j];248if(!IsEquation[n])249continue;250IntegerPL NegVal=Supps[n][dim1];251bool is_zero;252// cout << Supps[p];253// cout << Supps[n];254vector<IntegerPL> new_equ=FM_comb(PosVal,Supps[n],NegVal,Supps[p],is_zero);255// cout << "zero " << is_zero << endl;256// cout << "=====================" << endl;257if(is_zero)258continue;259EqusProj.append(new_equ);260}261}262263for(size_t i=0;i<Pos.size();++i){ // match pos inequalities with a negative equation264size_t p=Pos[i];265if(IsEquation[p])266continue;267IntegerPL PosVal=Supps[p][dim1];268IntegerPL NegVal=Supps[NegEquAt][dim1];269vector<IntegerPL> new_supp(dim);270bool is_zero;271new_supp=FM_comb(PosVal,Supps[NegEquAt],NegVal,Supps[p],is_zero);272/* cout << Supps[NegEquAt];273cout << Supps[p];274cout << new_supp;275cout << "zero " << is_zero << endl;276cout << "+++++++++++++++++++++" << endl; */277if(is_zero) // cannot happen, but included for analogy278continue;279SuppsProj.append(new_supp);280NewInd.push_back(Ind[p]);281}282283for(size_t j=0;j<Neg.size();++j){ // match neg inequalities with a posizive equation284size_t n=Neg[j];285if(IsEquation[n])286continue;287IntegerPL PosVal=Supps[PosEquAt][dim1];288IntegerPL NegVal=Supps[n][dim1];289vector<IntegerPL> new_supp(dim);290bool is_zero;291new_supp=FM_comb(PosVal,Supps[n],NegVal,Supps[PosEquAt],is_zero);292/* cout << Supps[PosEquAt];293cout << Supps[n];294cout << new_supp;295cout << "zero " << is_zero << endl;296cout << "=====================" << endl;*/297298if(is_zero) // cannot happen, but included for analogy299continue;300SuppsProj.append(new_supp);301NewInd.push_back(Ind[n]);302}303}304305// cout << "Nach RGU " << EqusProj.nr_of_rows() << " " << SuppsProj.nr_of_rows() << endl;306307if(!rank_goes_up && !is_parallelotope){ // must match pos and neg hyperplanes308309skip_remaining=false;310311size_t min_nr_vertices=rank-2;312/*if(rank>=3){313min_nr_vertices=1;314for(long i=0;i<(long) rank -3;++i)315min_nr_vertices*=2;316317}*/318319#pragma omp parallel for schedule(dynamic)320for(size_t i=0;i<Pos.size();++i){321322if (skip_remaining) continue;323324#ifndef NCATCH325try {326#endif327328INTERRUPT_COMPUTATION_BY_EXCEPTION329330size_t p=Pos[i];331IntegerPL PosVal=Supps[p][dim1];332vector<key_t> PosKey;333for(size_t k=0;k<Ind[i].size();++k)334if(Ind[p][k])335PosKey.push_back(k);336337for(size_t j=0;j<Neg.size();++j){338size_t n=Neg[j];339// // to give a facet of the extended cone340// match incidence vectors341boost::dynamic_bitset<> incidence(TRUE.size());342size_t nr_match=0;343vector<key_t> CommonKey;344for(size_t k=0;k<PosKey.size();++k)345if(Ind[n][PosKey[k]]){346incidence[PosKey[k]]=true;347CommonKey.push_back(PosKey[k]);348nr_match++;349}350if(rank>=2 && nr_match<min_nr_vertices) // cannot make subfacet of augmented cone351continue;352353bool IsSubfacet=true;354for(size_t k=0;k<Supps.nr_of_rows();++k){355if(k==p || k==n || IsEquation[k])356continue;357bool contained=true;358for(size_t j=0;j<CommonKey.size();++j){359if(!Ind[k][CommonKey[j]]){360contained=false;361break;362}363}364if(contained){365IsSubfacet=false;366break;367}368}369if(!IsSubfacet)370continue;371//}372373IntegerPL NegVal=Supps[n][dim1];374vector<IntegerPL> new_supp(dim);375bool is_zero;376new_supp=FM_comb(PosVal,Supps[n],NegVal,Supps[p],is_zero);377if(is_zero) // linear combination is 0378continue;379380if(nr_match==TRUE.size()){ // gives an equation381#pragma omp critical(NEWEQ)382EqusProj.append(new_supp);383continue;384}385#pragma omp critical(NEWSUPP)386{387SuppsProj.append(new_supp);388NewInd.push_back(incidence);389}390}391392#ifndef NCATCH393} catch(const std::exception& ) {394tmp_exception = std::current_exception();395skip_remaining = true;396#pragma omp flush(skip_remaining)397}398#endif399}400401} // !rank_goes_up && !is_parallelotope402403if(!rank_goes_up && is_parallelotope){ // must match pos and neg hyperplanes404405size_t codim=dim1-1; // the minimal codim a face of the original cone must have406// in order to project to a subfacet of the current one407size_t original_dim=Pair[0].size()+1;408size_t max_number_containing_factes=original_dim-codim;409410skip_remaining=false;411412size_t nr_pos=Pos.size();413//if(nr_pos>10000)414// nr_pos=10000;415size_t nr_neg=Neg.size();416// if(nr_neg>10000)417// nr_neg=10000;418419#pragma omp parallel for schedule(dynamic)420for(size_t i=0;i<nr_pos;++i){421422if (skip_remaining) continue;423424#ifndef NCATCH425try {426#endif427428INTERRUPT_COMPUTATION_BY_EXCEPTION429430size_t p=Pos[i];431IntegerPL PosVal=Supps[p][dim1];432433for(size_t j=0;j<nr_neg;++j){434size_t n=Neg[j];435boost::dynamic_bitset<> IntersectionPair(Pair[p].size());436size_t nr_hyp_intersection=0;437bool in_parallel_hyperplanes=false;438bool codim_too_small=false;439440for(size_t k=0;k<Pair[p].size();++k){ // run over all pairs441if(Pair[p][k] || Pair[n][k]){442nr_hyp_intersection++;443IntersectionPair[k]=true;444if(nr_hyp_intersection> max_number_containing_factes){445codim_too_small=true;446break;447}448}449if(Pair[p][k] && Pair[n][k]){450if(ParaInPair[p][k]!=ParaInPair[n][k]){451in_parallel_hyperplanes=true;452break;453}454}455}456if(in_parallel_hyperplanes || codim_too_small)457continue;458459boost::dynamic_bitset<> IntersectionParaInPair(Pair[p].size());460for(size_t k=0;k<ParaInPair[p].size();++k){461if(Pair[p][k])462IntersectionParaInPair[k]=ParaInPair[p][k];463else464if(Pair[n][k])465IntersectionParaInPair[k]=ParaInPair[n][k];466}467468// we must nevertheless use the comparison test469bool IsSubfacet=true;470if(!no_crunch){471for(size_t k=0;k<Supps.nr_of_rows();++k){472if(k==p || k==n || IsEquation[k])473continue;474bool contained=true;475476for(size_t u=0;u<IntersectionPair.size();++u){477if(Pair[k][u] && !IntersectionPair[u]){ // hyperplane k contains facet of Supp478contained=false; // not our intersection479continue;480}481if(Pair[k][u] && IntersectionPair[u]){482if(ParaInPair[k][u]!=IntersectionParaInPair[u]){ // they are contained in parallel483contained=false; // original facets484continue;485}486}487}488489if(contained){490IsSubfacet=false;491break;492}493}494}495if(!IsSubfacet)496continue;497498IntegerPL NegVal=Supps[n][dim1];499bool dummy;500vector<IntegerPL> new_supp=FM_comb(PosVal,Supps[n],NegVal,Supps[p],dummy);501#pragma omp critical(NEWSUPP)502{503SuppsProj.append(new_supp);504NewPair.push_back(IntersectionPair);505NewParaInPair.push_back(IntersectionParaInPair);506}507}508509#ifndef NCATCH510} catch(const std::exception& ) {511tmp_exception = std::current_exception();512skip_remaining = true;513#pragma omp flush(skip_remaining)514}515#endif516}517518#ifndef NCATCH519if (!(tmp_exception == 0)) std::rethrow_exception(tmp_exception);520#endif521522} // !rank_goes_up && is_parallelotope523524// cout << "Nach FM " << EqusProj.nr_of_rows() << " " << SuppsProj.nr_of_rows() << endl;525526Ind.clear(); // no longer needed527528EqusProj.resize_columns(dim1); // cut off the trailing 0529SuppsProj.resize_columns(dim1); // project hyperplanes530531// Equations have not yet been appended to support hypwerplanes532EqusProj.row_echelon(); // reduce equations533// cout << "Nach eche " << EqusProj.nr_of_rows() << endl;534/* for(size_t i=0;i<EqusProj.nr_of_rows(); ++i)535cout << EqusProj[i]; */536SuppsProj.append(EqusProj); // append them as pairs of inequalities537EqusProj.scalar_multiplication(-1);538SuppsProj.append(EqusProj);539540// Now we must make the new indicator matrix541// We must add indictor vectors for the equations542for(size_t i=0;i<2*EqusProj.nr_of_rows();++i)543NewInd.push_back(TRUE);544545if(dim1>1)546AllOrders[dim1]=order_supps(SuppsProj);547swap(AllSupps[dim1],SuppsProj);548549size_t new_rank=dim1-EqusProj.nr_of_rows();550551compute_projections(dim-1,NewInd, NewPair, NewParaInPair,new_rank);552}553554//---------------------------------------------------------------------------555template<typename IntegerPL,typename IntegerRet>556bool ProjectAndLift<IntegerPL,IntegerRet>::fiber_interval(IntegerRet& MinInterval, IntegerRet& MaxInterval,557const vector<IntegerRet>& base_point){558size_t dim=base_point.size()+1;559Matrix<IntegerPL>& Supps=AllSupps[dim];560vector<size_t>& Order=AllOrders[dim];561562bool FirstMin=true, FirstMax=true;563vector<IntegerPL> LiftedGen;564convert(LiftedGen,base_point);565// cout << LiftedGen;566size_t check_supps=Supps.nr_of_rows();567if(check_supps>1000 && dim<EmbDim)568check_supps=1000;569for(size_t j=0;j<check_supps;++j){570IntegerPL Den=Supps[Order[j]].back();571if(Den==0)572continue;573IntegerPL Num= -v_scalar_product_vectors_unequal_lungth(LiftedGen,Supps[Order[j]]);574// cout << "Num " << Num << endl;575IntegerRet Quot;576bool frac=int_quotient(Quot,Num,Den);577IntegerRet Bound=0;578//frac=(Num % Den !=0);579if(Den>0){ // we must produce a lower bound of the interval580if(Num>=0){ // true quot >= 0581Bound=Quot;582if(frac)583Bound++;584}585else // true quot < 0586Bound=-Quot;587if(FirstMin || Bound > MinInterval){588MinInterval=Bound;589FirstMin=false;590}591}592if(Den<0){ // we must produce an upper bound of the interval593if(Num >= 0){ // true quot <= 0594Bound=-Quot;595if(frac)596Bound--;597}598else // true quot > 0599Bound=Quot;600if(FirstMax || Bound < MaxInterval){601MaxInterval=Bound;602FirstMax=false;603}604}605if(!FirstMax && !FirstMin && MaxInterval<MinInterval)606return false; // interval empty607}608return true; // interval nonempty609}610611///---------------------------------------------------------------------------612template<typename IntegerPL,typename IntegerRet>613void ProjectAndLift<IntegerPL,IntegerRet>::lift_points_to_this_dim(list<vector<IntegerRet> >& Deg1Lifted,614const list<vector<IntegerRet> >& Deg1Proj){615616if(Deg1Proj.empty())617return;618size_t dim=Deg1Proj.front().size()+1;619size_t dim1=dim-1;620vector<list<vector<IntegerRet> > > Deg1Thread(omp_get_max_threads());621622bool skip_remaining;623#ifndef NCATCH624std::exception_ptr tmp_exception;625#endif626627skip_remaining=false;628int omp_start_level=omp_get_level();629630#pragma omp parallel631{632int tn;633if(omp_get_level()==omp_start_level)634tn=0;635else636tn = omp_get_ancestor_thread_num(omp_start_level+1);637638size_t nr_to_lift=Deg1Proj.size();639size_t ppos=0;640auto p=Deg1Proj.begin();641#pragma omp for schedule(dynamic)642for(size_t i=0;i<nr_to_lift;++i){643644if (skip_remaining) continue;645646for(; i > ppos; ++ppos, ++p) ;647for(; i < ppos; --ppos, --p) ;648649650#ifndef NCATCH651try {652#endif653654IntegerRet MinInterval=0, MaxInterval=0; // the fiber over *p is an interval -- 0 to make gcc happy655fiber_interval(MinInterval, MaxInterval, *p);656// cout << "Min " << MinInterval << " Max " << MaxInterval << endl;657for(IntegerRet k=MinInterval;k<=MaxInterval;++k){658659INTERRUPT_COMPUTATION_BY_EXCEPTION660661vector<IntegerRet> NewPoint(dim);662for(size_t j=0;j<dim1;++j)663NewPoint[j]=(*p)[j];664NewPoint[dim1]=k;665Deg1Thread[tn].push_back(NewPoint);666}667668#ifndef NCATCH669} catch(const std::exception& ) {670tmp_exception = std::current_exception();671skip_remaining = true;672#pragma omp flush(skip_remaining)673}674#endif675676} // lifting677} // pararllel678679#ifndef NCATCH680if (!(tmp_exception == 0)) std::rethrow_exception(tmp_exception);681#endif682683for(size_t i=0;i<Deg1Thread.size();++i)684Deg1Lifted.splice(Deg1Lifted.begin(),Deg1Thread[i]);685686/* Deg1.pretty_print(cout);687cout << "*******************" << endl; */688}689690///---------------------------------------------------------------------------691template<typename IntegerPL,typename IntegerRet>692void ProjectAndLift<IntegerPL,IntegerRet>::lift_points_by_generation(){693694assert(EmbDim>=2);695696list<vector<IntegerRet> > Deg1Lifted;697list<vector<IntegerRet> > Deg1Proj;698vector<IntegerRet> One(1,GD);699Deg1Proj.push_back(One);700701for(size_t i=2; i<=EmbDim;++i){702assert(Deg1Lifted.empty());703lift_points_to_this_dim(Deg1Lifted,Deg1Proj);704if(verbose)705verboseOutput() << "embdim " << i << " Deg1Elements " << Deg1Lifted.size() << endl;706if(i<EmbDim){707Deg1Proj.clear();708swap(Deg1Lifted,Deg1Proj);709}710}711712swap(Deg1Points,Deg1Lifted); // final result713/* if(verbose)714verboseOutput() << "Lifting done" << endl;*/715}716717///---------------------------------------------------------------------------718template<typename IntegerPL,typename IntegerRet>719void ProjectAndLift<IntegerPL,IntegerRet>::lift_point_recursively(vector<IntegerRet>& final_latt_point,720const vector<IntegerRet>& latt_point_proj){721722size_t dim1=latt_point_proj.size();723size_t dim=dim1+1;724size_t final_dim=AllSupps.size()-1;725726IntegerRet MinInterval=0, MaxInterval=0; // the fiber over Deg1Proj[i] is an interval -- 0 to make gcc happy727fiber_interval(MinInterval, MaxInterval, latt_point_proj);728for(IntegerRet k=MinInterval;k<=MaxInterval;++k){729730INTERRUPT_COMPUTATION_BY_EXCEPTION731732vector<IntegerRet> NewPoint(dim);733for(size_t j=0;j<dim1;++j)734NewPoint[j]=latt_point_proj[j];735NewPoint[dim1]=k;736if(dim==final_dim && NewPoint!=excluded_point){737final_latt_point=NewPoint;738break;739}740if(dim<final_dim){741lift_point_recursively(final_latt_point, NewPoint);742if(final_latt_point.size()>0)743break;744}745}746}747748///---------------------------------------------------------------------------749template<typename IntegerPL,typename IntegerRet>750void ProjectAndLift<IntegerPL,IntegerRet>::find_single_point(){751752size_t dim=AllSupps.size()-1;753assert(dim>=2);754755vector<IntegerRet> start(1,GD);756vector<IntegerRet> final_latt_point;757lift_point_recursively(final_latt_point,start);758if(final_latt_point.size()>0){759SingleDeg1Point=final_latt_point;760if(verbose)761verboseOutput() << "Found point" << endl;762}763else{764if(verbose)765verboseOutput() << "No point found" << endl;766}767}768769//---------------------------------------------------------------------------770template<typename IntegerPL,typename IntegerRet>771void ProjectAndLift<IntegerPL,IntegerRet>::initialize(const Matrix<IntegerPL>& Supps,size_t rank){772773EmbDim=Supps.nr_of_columns(); // our embedding dimension774AllSupps.resize(EmbDim+1);775AllOrders.resize(EmbDim+1);776AllSupps[EmbDim]=Supps;777AllOrders[EmbDim]=order_supps(Supps);778StartRank=rank;779GD=1; // the default choice780verbose=true;781is_parallelotope=false;782no_crunch=true;783}784785//---------------------------------------------------------------------------786template<typename IntegerPL,typename IntegerRet>787ProjectAndLift<IntegerPL,IntegerRet>::ProjectAndLift(){788789}790//---------------------------------------------------------------------------791// General constructor792template<typename IntegerPL,typename IntegerRet>793ProjectAndLift<IntegerPL,IntegerRet>::ProjectAndLift(const Matrix<IntegerPL>& Supps,794const vector<boost::dynamic_bitset<> >& Ind,size_t rank){795796initialize(Supps,rank);797StartInd=Ind;798}799800//---------------------------------------------------------------------------801// Constructor for parallelotopes802template<typename IntegerPL,typename IntegerRet>803ProjectAndLift<IntegerPL,IntegerRet>::ProjectAndLift(const Matrix<IntegerPL>& Supps,804const vector<boost::dynamic_bitset<> >& Pair,805const vector<boost::dynamic_bitset<> >& ParaInPair,size_t rank){806807initialize(Supps,rank);808is_parallelotope=true;809StartPair=Pair;810StartParaInPair=ParaInPair;811}812813//---------------------------------------------------------------------------814template<typename IntegerPL,typename IntegerRet>815void ProjectAndLift<IntegerPL,IntegerRet>::set_verbose(bool on_off){816verbose=on_off;817}818819//---------------------------------------------------------------------------820template<typename IntegerPL,typename IntegerRet>821void ProjectAndLift<IntegerPL,IntegerRet>::set_grading_denom(const IntegerRet GradingDenom){822GD=GradingDenom;823}824825//---------------------------------------------------------------------------826template<typename IntegerPL,typename IntegerRet>827void ProjectAndLift<IntegerPL,IntegerRet>::set_excluded_point(const vector<IntegerRet>& excl_point){828excluded_point=excl_point;829}830831//---------------------------------------------------------------------------832template<typename IntegerPL,typename IntegerRet>833void ProjectAndLift<IntegerPL,IntegerRet>::compute(bool all_points){834835// Project-and-lift for lattice points in a polytope.836// The first coordinate is homogenizing. Its value for polytope points ism set by GD so that837// a grading denominator 1=1 can be accomodated.838// We need only the support hyperplanes Supps and the facet-vertex incidence matrix Ind.839// Its rows correspond to facets.840841if(verbose)842verboseOutput() << "Projection" << endl;843compute_projections(EmbDim, StartInd,StartPair,StartParaInPair, StartRank);844if(all_points){845if(verbose)846verboseOutput() << "Lifting" << endl;847lift_points_by_generation();848}849else{850if(verbose)851verboseOutput() << "Try finding a lattice point" << endl;852find_single_point();853}854}855856//---------------------------------------------------------------------------857template<typename IntegerPL,typename IntegerRet>858void ProjectAndLift<IntegerPL,IntegerRet>::put_eg1Points_into(Matrix<IntegerRet>& LattPoints){859860while(!Deg1Points.empty()){861LattPoints.append(Deg1Points.front());862Deg1Points.pop_front();863}864}865866//---------------------------------------------------------------------------867template<typename IntegerPL,typename IntegerRet>868void ProjectAndLift<IntegerPL,IntegerRet>::put_single_point_into(vector<IntegerRet>& LattPoint){869870LattPoint=SingleDeg1Point;871}872//---------------------------------------------------------------------------873874#ifdef NMZ_MIC_OFFLOAD875#pragma offload_attribute (pop)876#endif877878} //end namespace libnormaliz879880881