Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418427/*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#include <list>2425#include "libQnormaliz/Qvector_operations.h"26#include "libQnormaliz/Qmap_operations.h"27#include "libQnormaliz/Qconvert.h"28#include "libQnormaliz/Qcone.h"29#include "libQnormaliz/Qfull_cone.h"3031namespace libQnormaliz {32using namespace std;3334// adds the signs inequalities given by Signs to Inequalities35template<typename Number>36Matrix<Number> sign_inequalities(const vector< vector<Number> >& Signs) {37if (Signs.size() != 1) {38throw BadInputException("ERROR: Bad signs matrix, has "39+ toString(Signs.size()) + " rows (should be 1)!");40}41size_t dim = Signs[0].size();42Matrix<Number> Inequ(0,dim);43vector<Number> ineq(dim,0);44for (size_t i=0; i<dim; i++) {45Number sign = Signs[0][i];46if (sign == 1 || sign == -1) {47ineq[i] = sign;48Inequ.append(ineq);49ineq[i] = 0;50} else if (sign != 0) {51throw BadInputException("Bad signs matrix, has entry "52+ toString(sign) + " (should be -1, 1 or 0)!");53}54}55return Inequ;56}5758template<typename Number>59Matrix<Number> strict_sign_inequalities(const vector< vector<Number> >& Signs) {60if (Signs.size() != 1) {61throw BadInputException("ERROR: Bad signs matrix, has "62+ toString(Signs.size()) + " rows (should be 1)!");63}64size_t dim = Signs[0].size();65Matrix<Number> Inequ(0,dim);66vector<Number> ineq(dim,0);67ineq[dim-1]=-1;68for (size_t i=0; i<dim-1; i++) { // last component of strict_signs always 069Number sign = Signs[0][i];70if (sign == 1 || sign == -1) {71ineq[i] = sign;72Inequ.append(ineq);73ineq[i] = 0;74} else if (sign != 0) {75throw BadInputException("Bad signs matrix, has entry "76+ toString(sign) + " (should be -1, 1 or 0)!");77}78}79return Inequ;80}8182template<typename Number>83vector<vector<Number> > find_input_matrix(const map< InputType, vector< vector<Number> > >& multi_input_data,84const InputType type){8586typename map< InputType , vector< vector<Number> > >::const_iterator it;87it = multi_input_data.find(type);88if (it != multi_input_data.end())89return(it->second);9091vector< vector<Number> > dummy;92return(dummy);93}9495template<typename Number>96void insert_column(vector< vector<Number> >& mat, size_t col, Number entry){9798vector<Number> help(mat[0].size()+1);99for(size_t i=0;i<mat.size();++i){100for(size_t j=0;j<col;++j)101help[j]=mat[i][j];102help[col]=entry;103for(size_t j=col;j<mat[i].size();++j)104help[j+1]=mat[i][j];105mat[i]=help;106}107}108109template<typename Number>110void insert_zero_column(vector< vector<Number> >& mat, size_t col){111// Number entry=0;112insert_column<Number>(mat,col,0);113}114115template<typename Number>116void Cone<Number>::homogenize_input(map< InputType, vector< vector<Number> > >& multi_input_data){117118typename map< InputType , vector< vector<Number> > >::iterator it;119it = multi_input_data.begin();120for(;it!=multi_input_data.end();++it){121switch(it->first){122case Type::dehomogenization:123throw BadInputException("Type dehomogenization not allowed with inhomogeneous input!");124break;125case Type::inhom_inequalities: // nothing to do126case Type::inhom_equations:127case Type::inhom_congruences:128case Type::polyhedron:129case Type::vertices:130case Type::support_hyperplanes:131case Type::grading: // already taken care of132break;133case Type::strict_inequalities:134insert_column<Number>(it->second,dim-1,-1);135break;136case Type::offset:137insert_column<Number>(it->second,dim-1,1);138break;139default: // is correct for signs and strict_signs !140insert_zero_column<Number>(it->second,dim-1);141break;142}143}144}145146//---------------------------------------------------------------------------147148template<typename Number>149Cone<Number>::Cone(InputType input_type, const vector< vector<Number> >& Input) {150// convert to a map151map< InputType, vector< vector<Number> > > multi_input_data;152multi_input_data[input_type] = Input;153process_multi_input(multi_input_data);154}155156template<typename Number>157Cone<Number>::Cone(InputType type1, const vector< vector<Number> >& Input1,158InputType type2, const vector< vector<Number> >& Input2) {159if (type1 == type2) {160throw BadInputException("Input types must pairwise different!");161}162// convert to a map163map< InputType, vector< vector<Number> > > multi_input_data;164multi_input_data[type1] = Input1;165multi_input_data[type2] = Input2;166process_multi_input(multi_input_data);167}168169template<typename Number>170Cone<Number>::Cone(InputType type1, const vector< vector<Number> >& Input1,171InputType type2, const vector< vector<Number> >& Input2,172InputType type3, const vector< vector<Number> >& Input3) {173if (type1 == type2 || type1 == type3 || type2 == type3) {174throw BadInputException("Input types must be pairwise different!");175}176// convert to a map177map< InputType, vector< vector<Number> > > multi_input_data;178multi_input_data[type1] = Input1;179multi_input_data[type2] = Input2;180multi_input_data[type3] = Input3;181process_multi_input(multi_input_data);182}183184template<typename Number>185Cone<Number>::Cone(const map< InputType, vector< vector<Number> > >& multi_input_data) {186process_multi_input(multi_input_data);187}188189//---------------------------------------------------------------------------190191template<typename Number>192Cone<Number>::Cone(InputType input_type, const Matrix<Number>& Input) {193// convert to a map194map< InputType, vector< vector<Number> > >multi_input_data;195multi_input_data[input_type] = Input.get_elements();196process_multi_input(multi_input_data);197}198199template<typename Number>200Cone<Number>::Cone(InputType type1, const Matrix<Number>& Input1,201InputType type2, const Matrix<Number>& Input2) {202if (type1 == type2) {203throw BadInputException("Input types must pairwise different!");204}205// convert to a map206map< InputType, vector< vector<Number> > > multi_input_data;207multi_input_data[type1] = Input1.get_elements();208multi_input_data[type2] = Input2.get_elements();209process_multi_input(multi_input_data);210}211212template<typename Number>213Cone<Number>::Cone(InputType type1, const Matrix<Number>& Input1,214InputType type2, const Matrix<Number>& Input2,215InputType type3, const Matrix<Number>& Input3) {216if (type1 == type2 || type1 == type3 || type2 == type3) {217throw BadInputException("Input types must be pairwise different!");218}219// convert to a map220map< InputType, vector< vector<Number> > > multi_input_data;221multi_input_data[type1] = Input1.get_elements();222multi_input_data[type2] = Input2.get_elements();223multi_input_data[type3] = Input3.get_elements();224process_multi_input(multi_input_data);225}226227template<typename Number>228Cone<Number>::Cone(const map< InputType, Matrix<Number> >& multi_input_data_Matrix){229map< InputType, vector< vector<Number> > > multi_input_data;230auto it = multi_input_data_Matrix.begin();231for(; it != multi_input_data_Matrix.end(); ++it){232multi_input_data[it->first]=it->second.get_elements();233}234process_multi_input(multi_input_data);235}236237//---------------------------------------------------------------------------238239240template<typename Number>241void Cone<Number>::process_multi_input(const map< InputType, vector< vector<Number> > >& multi_input_data_const) {242initialize();243map< InputType, vector< vector<Number> > > multi_input_data(multi_input_data_const);244// find basic input type245bool lattice_ideal_input=false;246bool inhom_input=false;247size_t nr_latt_gen=0, nr_cone_gen=0;248249auto it = multi_input_data.begin();250for(; it != multi_input_data.end(); ++it)251for(size_t i=0;i < it->second.size();++i){252for(size_t j=0;j<it->second[i].size();++j)253it->second[i][j].canonicalize();254v_simplify(it->second[i]);255}256257inequalities_present=false; //control choice of positive orthant258259if( exists_element(multi_input_data,Type::lattice)260|| exists_element(multi_input_data,Type::cone_and_lattice)261|| exists_element(multi_input_data,Type::congruences)262|| exists_element(multi_input_data,Type::inhom_congruences)263|| exists_element(multi_input_data,Type::dehomogenization)264|| exists_element(multi_input_data,Type::offset)265|| exists_element(multi_input_data,Type::grading))266throw BadInputException("Input types not allowed for field coefficients");267268// NEW: Empty matrix have syntactical influence269it = multi_input_data.begin();270for(; it != multi_input_data.end(); ++it) {271switch (it->first) {272case Type::inhom_inequalities:273case Type::inhom_equations:274case Type::inhom_congruences:275case Type::strict_inequalities:276case Type::strict_signs:277inhom_input=true;278case Type::signs:279case Type::inequalities:280case Type::equations:281case Type::congruences:282break;283case Type::lattice_ideal:284lattice_ideal_input=true;285break;286case Type::polyhedron:287inhom_input=true;288case Type::integral_closure:289case Type::rees_algebra:290case Type::polytope:291case Type::cone:292case Type::subspace:293nr_cone_gen++;294break;295case Type::normalization:296case Type::cone_and_lattice:297nr_cone_gen++;298case Type::lattice:299case Type::saturation:300nr_latt_gen++;301break;302case Type::vertices:303case Type::offset:304inhom_input=true;305default:306break;307}308309switch (it->first) { // chceck existence of inrqualities310case Type::inhom_inequalities:311case Type::strict_inequalities:312case Type::strict_signs:313case Type::signs:314case Type::inequalities:315case Type::excluded_faces:316case Type::support_hyperplanes:317inequalities_present=true;318default:319break;320}321322}323324bool gen_error=false;325if(nr_cone_gen>2)326gen_error=true;327328if(nr_cone_gen==2 && (!exists_element(multi_input_data,Type::subspace)329|| !(exists_element(multi_input_data,Type::cone)330|| exists_element(multi_input_data,Type::cone_and_lattice)331|| exists_element(multi_input_data,Type::integral_closure)332|| exists_element(multi_input_data,Type::normalization) ) )333)334gen_error=true;335336if(gen_error){337throw BadInputException("Illegal combination of cone generator types!");338}339340341if(nr_latt_gen>1){342throw BadInputException("Only one matrix of lattice generators allowed!");343}344if(lattice_ideal_input){345if(multi_input_data.size() > 2 || (multi_input_data.size()==2 && !exists_element(multi_input_data,Type::grading))){346throw BadInputException("Only grading allowed with lattice_ideal!");347}348}349if(inhom_input){350if(exists_element(multi_input_data,Type::dehomogenization) || exists_element(multi_input_data,Type::support_hyperplanes)){351throw BadInputException("Types dehomogenization and support_hyperplanes not allowed with inhomogeneous input!");352}353}354if(inhom_input || exists_element(multi_input_data,Type::dehomogenization)){355if(exists_element(multi_input_data,Type::rees_algebra) || exists_element(multi_input_data,Type::polytope)){356throw BadInputException("Types polytope and rees_algebra not allowed with inhomogeneous input or hehomogenizaion!");357}358if(exists_element(multi_input_data,Type::excluded_faces)){359throw BadInputException("Type excluded_faces not allowed with inhomogeneous input or dehomogenization!");360}361}362if(exists_element(multi_input_data,Type::grading) && exists_element(multi_input_data,Type::polytope)){363throw BadInputException("No explicit grading allowed with polytope!");364}365366// remove empty matrices367it = multi_input_data.begin();368for(; it != multi_input_data.end();) {369if (it->second.size() == 0)370multi_input_data.erase(it++);371else372++it;373}374375if(multi_input_data.size()==0){376throw BadInputException("All input matrices empty!");377}378379//determine dimension380it = multi_input_data.begin();381size_t inhom_corr = 0; // correction in the inhom_input case382if (inhom_input) inhom_corr = 1;383dim = it->second.front().size() - type_nr_columns_correction(it->first) + inhom_corr;384385// We now process input types that are independent of generators, constraints, lattice_ideal386// check for excluded faces387ExcludedFaces = find_input_matrix(multi_input_data,Type::excluded_faces);388PreComputedSupportHyperplanes = find_input_matrix(multi_input_data,Type::support_hyperplanes);389390// check consistence of dimension391it = multi_input_data.begin();392size_t test_dim;393for (; it != multi_input_data.end(); ++it) {394test_dim = it->second.front().size() - type_nr_columns_correction(it->first) + inhom_corr;395if (test_dim != dim) {396throw BadInputException("Inconsistent dimensions in input!");397}398}399400if(inhom_input)401homogenize_input(multi_input_data);402403// check for dehomogenization404vector< vector<Number> > lf = find_input_matrix(multi_input_data,Type::dehomogenization);405if (lf.size() > 1) {406throw BadInputException("Bad dehomogenization, has "407+ toString(lf.size()) + " rows (should be 1)!");408}409if(lf.size()==1){410setDehomogenization(lf[0]);411}412413// now we can unify implicit and explicit truncation414// Note: implicit and explicit truncation have already been excluded415if (inhom_input) {416Dehomogenization.resize(dim,0),417Dehomogenization[dim-1]=1;418is_Computed.set(ConeProperty::Dehomogenization);419}420if(isComputed(ConeProperty::Dehomogenization))421inhomogeneous=true;422423if(lattice_ideal_input){424prepare_input_lattice_ideal(multi_input_data);425}426427Matrix<Number> LatticeGenerators(0,dim);428prepare_input_generators(multi_input_data, LatticeGenerators);429430Matrix<Number> Equations(0,dim), Congruences(0,dim+1);431Matrix<Number> Inequalities(0,dim);432prepare_input_constraints(multi_input_data,Equations,Congruences,Inequalities);433434// set default values if necessary435if(inhom_input && LatticeGenerators.nr_of_rows()!=0 && !exists_element(multi_input_data,Type::offset)){436vector<Number> offset(dim);437offset[dim-1]=1;438LatticeGenerators.append(offset);439}440if(inhom_input && Generators.nr_of_rows()!=0 && !exists_element(multi_input_data,Type::vertices)441&& !exists_element(multi_input_data,Type::polyhedron)){442vector<Number> vertex(dim);443vertex[dim-1]=1;444Generators.append(vertex);445}446447if(Inequalities.nr_of_rows()>0 && Generators.nr_of_rows()>0){ // eliminate superfluous inequalities448vector<key_t> essential;449for(size_t i=0;i<Inequalities.nr_of_rows();++i){450for (size_t j=0;j<Generators.nr_of_rows();++j){451if(v_scalar_product(Inequalities[i],Generators[j])<0){452essential.push_back(i);453break;454}455}456}457if(essential.size()<Inequalities.nr_of_rows())458Inequalities=Inequalities.submatrix(essential);459}460461// cout << "Ineq " << Inequalities.nr_of_rows() << endl;462463process_lattice_data(LatticeGenerators,Congruences,Equations);464465bool cone_sat_eq=no_lattice_restriction;466bool cone_sat_cong=no_lattice_restriction;467468// cout << "nolatrest " << no_lattice_restriction << endl;469470if(Inequalities.nr_of_rows()==0 && Generators.nr_of_rows()!=0){471if(!no_lattice_restriction){472cone_sat_eq=true;473for(size_t i=0;i<Generators.nr_of_rows() && cone_sat_eq;++i)474for(size_t j=0;j<Equations.nr_of_rows() && cone_sat_eq ;++j)475if(v_scalar_product(Generators[i],Equations[j])!=0){476cone_sat_eq=false;477}478}479480if(cone_sat_eq && !cone_sat_cong){ // multiply generators by anniullator mod sublattice481for(size_t i=0;i<Generators.nr_of_rows();++i)482v_scalar_multiplication(Generators[i],BasisChange.getAnnihilator());483cone_sat_cong=true;484}485}486487if((Inequalities.nr_of_rows()!=0 || !cone_sat_eq) && Generators.nr_of_rows()!=0){488Sublattice_Representation<Number> ConeLatt(Generators,true);489Full_Cone<Number> TmpCone(ConeLatt.to_sublattice(Generators));490TmpCone.dualize_cone();491Inequalities.append(ConeLatt.from_sublattice_dual(TmpCone.Support_Hyperplanes));492Generators=Matrix<Number>(0,dim); // Generators now converted into inequalities493}494495assert(Inequalities.nr_of_rows()==0 || Generators.nr_of_rows()==0);496497if(Generators.nr_of_rows()==0)498prepare_input_type_4(Inequalities); // inserts default inequalties if necessary499else{500is_Computed.set(ConeProperty::Generators);501is_Computed.set(ConeProperty::Sublattice);502}503504checkDehomogenization();505506setWeights(); // make matrix of weights for sorting507508if(PreComputedSupportHyperplanes.nr_of_rows()>0){509check_precomputed_support_hyperplanes();510SupportHyperplanes=PreComputedSupportHyperplanes;511is_Computed.set(ConeProperty::SupportHyperplanes);512}513514BasisChangePointed=BasisChange;515516is_Computed.set(ConeProperty::IsInhomogeneous);517is_Computed.set(ConeProperty::EmbeddingDim);518519/* if(ExcludedFaces.nr_of_rows()>0){ // Nothing to check anymore520check_excluded_faces();521} */522523/*524cout <<"-----------------------" << endl;525cout << "Gen " << endl;526Generators.pretty_print(cout);527cout << "Supp " << endl;528SupportHyperplanes.pretty_print(cout);529cout << "A" << endl;530BasisChange.get_A().pretty_print(cout);531cout << "B" << endl;532BasisChange.get_B().pretty_print(cout);533cout <<"-----------------------" << endl;534*/535}536537538//---------------------------------------------------------------------------539540template<typename Number>541void Cone<Number>::prepare_input_constraints(const map< InputType, vector< vector<Number> > >& multi_input_data,542Matrix<Number>& Equations, Matrix<Number>& Congruences, Matrix<Number>& Inequalities) {543544Matrix<Number> Signs(0,dim), StrictSigns(0,dim);545546SupportHyperplanes=Matrix<Number>(0,dim);547548typename map< InputType , vector< vector<Number> > >::const_iterator it=multi_input_data.begin();549550it = multi_input_data.begin();551for (; it != multi_input_data.end(); ++it) {552553switch (it->first) {554case Type::strict_inequalities:555case Type::inequalities:556case Type::inhom_inequalities:557case Type::excluded_faces:558Inequalities.append(it->second);559break;560case Type::equations:561case Type::inhom_equations:562Equations.append(it->second);563break;564case Type::congruences:565case Type::inhom_congruences:566Congruences.append(it->second);567break;568case Type::signs:569Signs = sign_inequalities(it->second);570break;571case Type::strict_signs:572StrictSigns = strict_sign_inequalities(it->second);573break;574default:575break;576}577}578if(!BC_set) compose_basis_change(Sublattice_Representation<Number>(dim));579Matrix<Number> Help(Signs); // signs first !!580Help.append(StrictSigns); // then strict signs581Help.append(Inequalities);582Inequalities=Help;583}584585//---------------------------------------------------------------------------586template<typename Number>587void Cone<Number>::prepare_input_generators(map< InputType, vector< vector<Number> > >& multi_input_data, Matrix<Number>& LatticeGenerators) {588589if(exists_element(multi_input_data,Type::vertices)){590for(size_t i=0;i<multi_input_data[Type::vertices].size();++i)591if(multi_input_data[Type::vertices][i][dim-1] <= 0) {592throw BadInputException("Vertex has non-positive denominator!");593}594}595596if(exists_element(multi_input_data,Type::polyhedron)){597for(size_t i=0;i<multi_input_data[Type::polyhedron].size();++i)598if(multi_input_data[Type::polyhedron][i][dim-1] < 0) {599throw BadInputException("Polyhedron vertex has negative denominator!");600}601}602603typename map< InputType , vector< vector<Number> > >::const_iterator it=multi_input_data.begin();604// find specific generator type -- there is only one, as checked already605606normalization=false;607608// check for subspace609BasisMaxSubspace = find_input_matrix(multi_input_data,Type::subspace);610if(BasisMaxSubspace.nr_of_rows()==0)611BasisMaxSubspace=Matrix<Number>(0,dim);612613vector<Number> neg_sum_subspace(dim,0);614for(size_t i=0;i<BasisMaxSubspace.nr_of_rows();++i)615neg_sum_subspace=v_add(neg_sum_subspace,BasisMaxSubspace[i]);616v_scalar_multiplication<Number>(neg_sum_subspace,-1);617618619Generators=Matrix<Number>(0,dim);620for(; it != multi_input_data.end(); ++it) {621switch (it->first) {622case Type::normalization:623case Type::cone_and_lattice:624normalization=true;625LatticeGenerators.append(it->second);626if(BasisMaxSubspace.nr_of_rows()>0)627LatticeGenerators.append(BasisMaxSubspace);628case Type::vertices:629case Type::polyhedron:630case Type::cone:631case Type::integral_closure:632Generators.append(it->second);633break;634case Type::subspace:635Generators.append(it->second);636Generators.append(neg_sum_subspace);637break;638case Type::polytope:639Generators.append(prepare_input_type_2(it->second));640break;641case Type::rees_algebra:642Generators.append(prepare_input_type_3(it->second));643break;644case Type::lattice:645LatticeGenerators.append(it->second);646break;647case Type::saturation:648LatticeGenerators.append(it->second);649LatticeGenerators.saturate();650break;651case Type::offset:652if(it->second.size()>1){653throw BadInputException("Only one offset allowed!");654}655LatticeGenerators.append(it->second);656break;657default: break;658}659}660}661662//---------------------------------------------------------------------------663664template<typename Number>665void Cone<Number>::process_lattice_data(const Matrix<Number>& LatticeGenerators, Matrix<Number>& Congruences, Matrix<Number>& Equations) {666667if(!BC_set)668compose_basis_change(Sublattice_Representation<Number>(dim));669670bool no_constraints=(Congruences.nr_of_rows()==0) && (Equations.nr_of_rows()==0);671bool only_cone_gen=(Generators.nr_of_rows()!=0) && no_constraints && (LatticeGenerators.nr_of_rows()==0);672673no_lattice_restriction=true;674675if(only_cone_gen){676Sublattice_Representation<Number> Basis_Change(Generators,true);677compose_basis_change(Basis_Change);678return;679}680681if(normalization && no_constraints){682Sublattice_Representation<Number> Basis_Change(Generators,false);683compose_basis_change(Basis_Change);684return;685}686687no_lattice_restriction=false;688689if(Generators.nr_of_rows()!=0){690Equations.append(Generators.kernel());691}692693if(LatticeGenerators.nr_of_rows()!=0){694Sublattice_Representation<Number> GenSublattice(LatticeGenerators,false);695if((Equations.nr_of_rows()==0) && (Congruences.nr_of_rows()==0)){696compose_basis_change(GenSublattice);697return;698}699// Congruences.append(GenSublattice.getCongruencesMatrix());700Equations.append(GenSublattice.getEquationsMatrix());701}702703/* if (Congruences.nr_of_rows() > 0) {704bool zero_modulus;705Matrix<Number> Ker_Basis=Congruences.solve_congruences(zero_modulus);706if(zero_modulus) {707throw BadInputException("Modulus 0 in congruence!");708}709Sublattice_Representation<Number> Basis_Change(Ker_Basis,false);710compose_basis_change(Basis_Change);711}*/712713if (Equations.nr_of_rows()>0) {714Matrix<Number> Ker_Basis=BasisChange.to_sublattice_dual(Equations).kernel();715Sublattice_Representation<Number> Basis_Change(Ker_Basis,true);716compose_basis_change(Basis_Change);717}718}719720//---------------------------------------------------------------------------721722template<typename Number>723void Cone<Number>::prepare_input_type_4(Matrix<Number>& Inequalities) {724725if (!inequalities_present) {726if (verbose) {727verboseOutput() << "No inequalities specified in constraint mode, using non-negative orthant." << endl;728}729if(inhomogeneous){730vector<Number> test(dim);731test[dim-1]=1;732size_t matsize=dim;733if(test==Dehomogenization) // in this case "last coordinate >= 0" will come in through the dehomogenization734matsize=dim-1; // we don't check for any other coincidence735Inequalities= Matrix<Number>(matsize,dim);736for(size_t j=0;j<matsize;++j)737Inequalities[j][j]=1;738}739else740Inequalities = Matrix<Number>(dim);741}742if(inhomogeneous)743SupportHyperplanes.append(Dehomogenization);744SupportHyperplanes.append(Inequalities);745}746747748//---------------------------------------------------------------------------749750/* polytope input */751template<typename Number>752Matrix<Number> Cone<Number>::prepare_input_type_2(const vector< vector<Number> >& Input) {753size_t j;754size_t nr = Input.size();755//append a column of 1756Matrix<Number> Generators(nr, dim);757for (size_t i=0; i<nr; i++) {758for (j=0; j<dim-1; j++)759Generators[i][j] = Input[i][j];760Generators[i][dim-1]=1;761}762// use the added last component as grading763Grading = vector<Number>(dim,0);764Grading[dim-1] = 1;765is_Computed.set(ConeProperty::Grading);766GradingDenom=1;767is_Computed.set(ConeProperty::GradingDenom);768return Generators;769}770771//---------------------------------------------------------------------------772773/* rees input */774template<typename Number>775Matrix<Number> Cone<Number>::prepare_input_type_3(const vector< vector<Number> >& InputV) {776Matrix<Number> Input(InputV);777int i,j,nr_rows=Input.nr_of_rows(), nr_columns=Input.nr_of_columns();778// create cone generator matrix779Matrix<Number> Full_Cone_Generators(nr_rows+nr_columns,nr_columns+1,0);780for (i = 0; i < nr_columns; i++) {781Full_Cone_Generators[i][i]=1;782}783for(i=0; i<nr_rows; i++){784Full_Cone_Generators[i+nr_columns][nr_columns]=1;785for(j=0; j<nr_columns; j++) {786Full_Cone_Generators[i+nr_columns][j]=Input[i][j];787}788}789790return Full_Cone_Generators;791}792793794//---------------------------------------------------------------------------795796template<typename Number>797void Cone<Number>::prepare_input_lattice_ideal(map< InputType, vector< vector<Number> > >& multi_input_data) {798799Matrix<Number> Binomials(find_input_matrix(multi_input_data,Type::lattice_ideal));800801if (Grading.size()>0) {802//check if binomials are homogeneous803vector<Number> degrees = Binomials.MxV(Grading);804for (size_t i=0; i<degrees.size(); ++i) {805if (degrees[i]!=0) {806throw BadInputException("Grading gives non-zero value "807+ toString(degrees[i]) + " for binomial "808+ toString(i+1) + "!");809}810if (Grading[i] <0) {811throw BadInputException("Grading gives negative value "812+ toString(Grading[i]) + " for generator "813+ toString(i+1) + "!");814}815}816}817818Matrix<Number> Gens=Binomials.kernel().transpose();819Full_Cone<Number> FC(Gens);820FC.verbose=verbose;821if (verbose) verboseOutput() << "Computing a positive embedding..." << endl;822823FC.dualize_cone();824Matrix<Number> Supp_Hyp=FC.getSupportHyperplanes().sort_lex();825Matrix<Number> Selected_Supp_Hyp_Trans=(Supp_Hyp.submatrix(Supp_Hyp.max_rank_submatrix_lex())).transpose();826Matrix<Number> Positive_Embedded_Generators=Gens.multiplication(Selected_Supp_Hyp_Trans);827// GeneratorsOfToricRing = Positive_Embedded_Generators;828// is_Computed.set(ConeProperty::GeneratorsOfToricRing);829dim = Positive_Embedded_Generators.nr_of_columns();830multi_input_data.insert(make_pair(Type::normalization,Positive_Embedded_Generators.get_elements())); // this is the cone defined by the binomials831832if (Grading.size()>0) {833// solve GeneratorsOfToricRing * grading = old_grading834Number dummyDenom;835// Grading must be set directly since map entry has been processed already836Grading = Positive_Embedded_Generators.solve_rectangular(Grading,dummyDenom);837if (Grading.size() != dim) {838errorOutput() << "Grading could not be transferred!"<<endl;839is_Computed.set(ConeProperty::Grading, false);840}841}842}843844/* only used by the constructors */845template<typename Number>846void Cone<Number>::initialize() {847BC_set=false;848is_Computed = bitset<ConeProperty::EnumSize>(); //initialized to false849dim = 0;850unit_group_index = 1;851inhomogeneous=false;852triangulation_is_nested = false;853triangulation_is_partial = false;854verbose = libQnormaliz::verbose; //take the global default855if (using_GMP<Number>()) {856change_integer_type = true;857} else {858change_integer_type = false;859}860}861862//---------------------------------------------------------------------------863864template<typename Number>865void Cone<Number>::compose_basis_change(const Sublattice_Representation<Number>& BC) {866if (BC_set) {867BasisChange.compose(BC);868} else {869BasisChange = BC;870BC_set = true;871}872}873//---------------------------------------------------------------------------874template<typename Number>875void Cone<Number>::check_precomputed_support_hyperplanes(){876877if (isComputed(ConeProperty::Generators)) {878// check if the inequalities are at least valid879// if (PreComputedSupportHyperplanes.nr_of_rows() != 0) {880Number sp;881for (size_t i = 0; i < Generators.nr_of_rows(); ++i) {882for (size_t j = 0; j < PreComputedSupportHyperplanes.nr_of_rows(); ++j) {883if ((sp = v_scalar_product(Generators[i], PreComputedSupportHyperplanes[j])) < 0) {884throw BadInputException("Precomputed inequality " + toString(j)885+ " is not valid for generator " + toString(i)886+ " (value " + toString(sp) + ")");887}888}889}890// }891}892}893894//---------------------------------------------------------------------------895896template<typename Number>897bool Cone<Number>::setVerbose (bool v) {898//we want to return the old value899bool old = verbose;900verbose = v;901return old;902}903904//---------------------------------------------------------------------------905906template<typename Number>907void Cone<Number>::checkDehomogenization () {908if(Dehomogenization.size()>0){909vector<Number> test=Generators.MxV(Dehomogenization);910for(size_t i=0;i<test.size();++i)911if(test[i]<0){912throw BadInputException(913"Dehomogenization has has negative value on generator "914+ toString(Generators[i]));915}916}917}918919920//---------------------------------------------------------------------------921922template<typename Number>923void Cone<Number>::setWeights () {924925if(WeightsGrad.nr_of_columns()!=dim){926WeightsGrad=Matrix<Number> (0,dim); // weight matrix for ordering927}928if(Grading.size()>0 && WeightsGrad.nr_of_rows()==0)929WeightsGrad.append(Grading);930GradAbs=vector<bool>(WeightsGrad.nr_of_rows(),false);931}932//---------------------------------------------------------------------------933934template<typename Number>935void Cone<Number>::setDehomogenization (const vector<Number>& lf) {936if (lf.size() != dim) {937throw BadInputException("Dehomogenizing linear form has wrong dimension "938+ toString(lf.size()) + " (should be " + toString(dim) + ")");939}940Dehomogenization=lf;941is_Computed.set(ConeProperty::Dehomogenization);942}943944//---------------------------------------------------------------------------945946/* check what is computed */947template<typename Number>948bool Cone<Number>::isComputed(ConeProperty::Enum prop) const {949return is_Computed.test(prop);950}951952template<typename Number>953bool Cone<Number>::isComputed(ConeProperties CheckComputed) const {954return CheckComputed.reset(is_Computed).any();955}956957958/* getter */959960template<typename Number>961size_t Cone<Number>::getRank() {962compute(ConeProperty::Sublattice);963return BasisChange.getRank();964}965966967template<typename Number>968size_t Cone<Number>::getRecessionRank() {969compute(ConeProperty::RecessionRank);970return recession_rank;971}972973template<typename Number>974long Cone<Number>::getAffineDim() {975compute(ConeProperty::AffineDim);976return affine_dim;977}978979template<typename Number>980const Sublattice_Representation<Number>& Cone<Number>::getSublattice() {981compute(ConeProperty::Sublattice);982return BasisChange;983}984985template<typename Number>986const vector< vector<Number> >& Cone<Number>::getOriginalMonoidGenerators() {987compute(ConeProperty::OriginalMonoidGenerators);988return OriginalMonoidGenerators.get_elements();989}990template<typename Number>991size_t Cone<Number>::getNrOriginalMonoidGenerators() {992compute(ConeProperty::OriginalMonoidGenerators);993return OriginalMonoidGenerators.nr_of_rows();994}995996template<typename Number>997const vector< vector<Number> >& Cone<Number>::getMaximalSubspace() {998compute(ConeProperty::MaximalSubspace);999return BasisMaxSubspace.get_elements();1000}1001template<typename Number>1002const Matrix<Number>& Cone<Number>::getMaximalSubspaceMatrix() {1003compute(ConeProperty::MaximalSubspace);1004return BasisMaxSubspace;1005}1006template<typename Number>1007size_t Cone<Number>::getDimMaximalSubspace() {1008compute(ConeProperty::MaximalSubspace);1009return BasisMaxSubspace.nr_of_rows();1010}10111012template<typename Number>1013const Matrix<Number>& Cone<Number>::getGeneratorsMatrix() {1014compute(ConeProperty::Generators);1015return Generators;1016}10171018template<typename Number>1019const vector< vector<Number> >& Cone<Number>::getGenerators() {1020compute(ConeProperty::Generators);1021return Generators.get_elements();1022}10231024template<typename Number>1025size_t Cone<Number>::getNrGenerators() {1026compute(ConeProperty::Generators);1027return Generators.nr_of_rows();1028}10291030template<typename Number>1031const Matrix<Number>& Cone<Number>::getExtremeRaysMatrix() {1032compute(ConeProperty::ExtremeRays);1033return ExtremeRays;1034}1035template<typename Number>1036const vector< vector<Number> >& Cone<Number>::getExtremeRays() {1037compute(ConeProperty::ExtremeRays);1038return ExtremeRays.get_elements();1039}1040template<typename Number>1041size_t Cone<Number>::getNrExtremeRays() {1042compute(ConeProperty::ExtremeRays);1043return ExtremeRays.nr_of_rows();1044}10451046template<typename Number>1047const Matrix<Number>& Cone<Number>::getVerticesOfPolyhedronMatrix() {1048compute(ConeProperty::VerticesOfPolyhedron);1049return VerticesOfPolyhedron;1050}1051template<typename Number>1052const vector< vector<Number> >& Cone<Number>::getVerticesOfPolyhedron() {1053compute(ConeProperty::VerticesOfPolyhedron);1054return VerticesOfPolyhedron.get_elements();1055}1056template<typename Number>1057size_t Cone<Number>::getNrVerticesOfPolyhedron() {1058compute(ConeProperty::VerticesOfPolyhedron);1059return VerticesOfPolyhedron.nr_of_rows();1060}10611062template<typename Number>1063const Matrix<Number>& Cone<Number>::getSupportHyperplanesMatrix() {1064compute(ConeProperty::SupportHyperplanes);1065return SupportHyperplanes;1066}1067template<typename Number>1068const vector< vector<Number> >& Cone<Number>::getSupportHyperplanes() {1069compute(ConeProperty::SupportHyperplanes);1070return SupportHyperplanes.get_elements();1071}1072template<typename Number>1073size_t Cone<Number>::getNrSupportHyperplanes() {1074compute(ConeProperty::SupportHyperplanes);1075return SupportHyperplanes.nr_of_rows();1076}10771078template<typename Number>1079map< InputType , vector< vector<Number> > > Cone<Number>::getConstraints () {1080compute(ConeProperty::Sublattice, ConeProperty::SupportHyperplanes);1081map<InputType, vector< vector<Number> > > c;1082c[Type::inequalities] = SupportHyperplanes.get_elements();1083c[Type::equations] = BasisChange.getEquations();1084// c[Type::congruences] = BasisChange.getCongruences();1085return c;1086}10871088template<typename Number>1089const vector< pair<vector<key_t>,Number> >& Cone<Number>::getTriangulation() {1090compute(ConeProperty::Triangulation);1091return Triangulation;1092}10931094template<typename Number>1095const vector<vector<bool> >& Cone<Number>::getOpenFacets() {1096compute(ConeProperty::ConeDecomposition);1097return OpenFacets;1098}10991100template<typename Number>1101size_t Cone<Number>::getTriangulationSize() {1102compute(ConeProperty::TriangulationSize);1103return TriangulationSize;1104}11051106template<typename Number>1107Number Cone<Number>::getTriangulationDetSum() {1108compute(ConeProperty::TriangulationDetSum);1109return TriangulationDetSum;1110}11111112template<typename Number>1113vector<Number> Cone<Number>::getDehomogenization() {1114compute(ConeProperty::Dehomogenization);1115return Dehomogenization;1116}11171118template<typename Number>1119bool Cone<Number>::isPointed() {1120compute(ConeProperty::IsPointed);1121return pointed;1122}11231124template<typename Number>1125bool Cone<Number>::isInhomogeneous() {1126return inhomogeneous;1127}112811291130// the information about the triangulation will just be returned1131// if no triangulation was computed so far they return false1132template<typename Number>1133bool Cone<Number>::isTriangulationNested() {1134return triangulation_is_nested;1135}1136template<typename Number>1137bool Cone<Number>::isTriangulationPartial() {1138return triangulation_is_partial;1139}11401141//---------------------------------------------------------------------------11421143template<typename Number>1144ConeProperties Cone<Number>::compute(ConeProperty::Enum cp) {1145if (isComputed(cp)) return ConeProperties();1146return compute(ConeProperties(cp));1147}11481149template<typename Number>1150ConeProperties Cone<Number>::compute(ConeProperty::Enum cp1, ConeProperty::Enum cp2) {1151return compute(ConeProperties(cp1,cp2));1152}11531154template<typename Number>1155ConeProperties Cone<Number>::compute(ConeProperty::Enum cp1, ConeProperty::Enum cp2,1156ConeProperty::Enum cp3) {1157return compute(ConeProperties(cp1,cp2,cp3));1158}11591160//---------------------------------------------------------------------------11611162template<typename Number>1163void Cone<Number>::set_implicit_dual_mode(ConeProperties& ToCompute) {11641165if(ToCompute.test(ConeProperty::DualMode) || ToCompute.test(ConeProperty::PrimalMode)1166|| ToCompute.test(ConeProperty::ModuleGeneratorsOverOriginalMonoid)1167|| Generators.nr_of_rows()>0 || SupportHyperplanes.nr_of_rows() > 2*dim1168|| SupportHyperplanes.nr_of_rows()1169<= BasisChangePointed.getRank()+ 50/(BasisChangePointed.getRank()+1))1170return;1171if(ToCompute.test(ConeProperty::HilbertBasis))1172ToCompute.set(ConeProperty::DualMode);1173if(ToCompute.test(ConeProperty::Deg1Elements)1174&& !(ToCompute.test(ConeProperty::HilbertSeries) || ToCompute.test(ConeProperty::Multiplicity)))1175ToCompute.set(ConeProperty::DualMode);1176return;1177}11781179//---------------------------------------------------------------------------11801181// this wrapper allows us to save and restore class data that depend on ToCompute1182// and may therefore be destroyed if compute() is called by itself1183template<typename Number>1184ConeProperties Cone<Number>::recursive_compute(ConeProperties ToCompute) {11851186bool save_explicit_HilbertSeries=explicit_HilbertSeries;1187bool save_naked_dual= naked_dual;1188ToCompute=compute(ToCompute);1189explicit_HilbertSeries=save_explicit_HilbertSeries;1190naked_dual=save_naked_dual;1191return ToCompute;1192}11931194//---------------------------------------------------------------------------11951196template<typename Number>1197ConeProperties Cone<Number>::compute(ConeProperties ToCompute) {11981199ToCompute.check_Q_permissible();12001201if(ToCompute.test(ConeProperty::DefaultMode))1202ToCompute.set(ConeProperty::SupportHyperplanes);12031204change_integer_type=false;12051206if(BasisMaxSubspace.nr_of_rows()>0 && !isComputed(ConeProperty::MaximalSubspace)){1207BasisMaxSubspace=Matrix<Number>(0,dim);1208recursive_compute(ConeProperty::MaximalSubspace);1209}121012111212ToCompute.reset(is_Computed);1213ToCompute.set_preconditions();1214ToCompute.prepare_compute_options(inhomogeneous);1215ToCompute.check_sanity(inhomogeneous);12161217/* preparation: get generators if necessary */1218compute_generators();12191220if (!isComputed(ConeProperty::Generators)) {1221throw FatalException("Could not get Generators.");1222}12231224ToCompute.reset(is_Computed); // already computed1225if (ToCompute.none()) {1226return ToCompute;1227}12281229// the actual computation12301231if (!change_integer_type) {1232compute_inner<Number>(ToCompute);1233}12341235complete_sublattice_comp(ToCompute);12361237/* check if everything is computed */1238ToCompute.reset(is_Computed); //remove what is now computed1239if (ToCompute.test(ConeProperty::Deg1Elements) && isComputed(ConeProperty::Grading)) {1240// this can happen when we were looking for a witness earlier1241recursive_compute(ToCompute);1242}1243if (!ToCompute.test(ConeProperty::DefaultMode) && ToCompute.goals().any()) {1244throw NotComputableException(ToCompute.goals());1245}1246ToCompute.reset_compute_options();1247return ToCompute;1248}12491250template<typename Number>1251template<typename NumberFC>1252void Cone<Number>::compute_inner(ConeProperties& ToCompute) {12531254if(ToCompute.test(ConeProperty::IsPointed) && Grading.size()==0){1255if (verbose) {1256verboseOutput()<< "Checking pointedness first"<< endl;1257}1258ConeProperties Dualize;1259Dualize.set(ConeProperty::SupportHyperplanes);1260Dualize.set(ConeProperty::ExtremeRays);1261recursive_compute(Dualize);1262}12631264Matrix<NumberFC> FC_Gens;12651266BasisChangePointed.convert_to_sublattice(FC_Gens, Generators);1267Full_Cone<NumberFC> FC(FC_Gens,!ToCompute.test(ConeProperty::ModuleGeneratorsOverOriginalMonoid));1268// !ToCompute.test(ConeProperty::ModuleGeneratorsOverOriginalMonoid) blocks make_prime in full_cone.cpp12691270/* activate bools in FC */12711272FC.verbose=verbose;12731274FC.inhomogeneous=inhomogeneous;12751276if (ToCompute.test(ConeProperty::Triangulation)) {1277FC.keep_triangulation = true;1278}1279if (ToCompute.test(ConeProperty::ConeDecomposition)) {1280FC.do_cone_dec = true;1281}12821283if (ToCompute.test(ConeProperty::TriangulationDetSum) ) {1284FC.do_determinants = true;1285}1286if (ToCompute.test(ConeProperty::TriangulationSize)) {1287FC.do_triangulation = true;1288}1289if (ToCompute.test(ConeProperty::KeepOrder)) {1290FC.keep_order = true;1291}12921293/* Give extra data to FC */1294if ( isComputed(ConeProperty::ExtremeRays) ) {1295FC.Extreme_Rays_Ind = ExtremeRaysIndicator;1296FC.is_Computed.set(ConeProperty::ExtremeRays);1297}12981299if (inhomogeneous){1300BasisChangePointed.convert_to_sublattice_dual_no_div(FC.Truncation, Dehomogenization);1301}13021303if (SupportHyperplanes.nr_of_rows()!=0) {1304BasisChangePointed.convert_to_sublattice_dual(FC.Support_Hyperplanes, SupportHyperplanes);1305}1306if (isComputed(ConeProperty::SupportHyperplanes)){1307FC.is_Computed.set(ConeProperty::SupportHyperplanes);1308FC.do_all_hyperplanes = false;1309}131013111312/* do the computation */13131314try {1315try {1316FC.compute();1317} catch (const NotIntegrallyClosedException& ) {1318}1319is_Computed.set(ConeProperty::Sublattice);1320// make sure we minimize the excluded faces if requested13211322extract_data(FC);1323if(isComputed(ConeProperty::IsPointed) && pointed)1324is_Computed.set(ConeProperty::MaximalSubspace);1325} catch(const NonpointedException& ) {1326is_Computed.set(ConeProperty::Sublattice);1327extract_data(FC);1328if(verbose){1329verboseOutput() << "Cone not pointed. Restarting computation." << endl;1330}1331FC=Full_Cone<NumberFC>(Matrix<NumberFC>(1)); // to kill the old FC (almost)1332Matrix<Number> Dual_Gen;1333Dual_Gen=BasisChangePointed.to_sublattice_dual(SupportHyperplanes);1334Sublattice_Representation<Number> Pointed(Dual_Gen,true); // sublattice of the dual lattice1335BasisMaxSubspace = BasisChangePointed.from_sublattice(Pointed.getEquationsMatrix());1336BasisMaxSubspace.simplify_rows();1337// check_vanishing_of_grading_and_dehom();1338BasisChangePointed.compose_dual(Pointed);1339is_Computed.set(ConeProperty::MaximalSubspace);1340// now we get the basis of the maximal subspace1341pointed = (BasisMaxSubspace.nr_of_rows() == 0);1342is_Computed.set(ConeProperty::IsPointed);1343compute_inner<NumberFC>(ToCompute);1344}1345}134613471348template<typename Number>1349void Cone<Number>::compute_generators() {1350//create Generators from SupportHyperplanes1351if (!isComputed(ConeProperty::Generators) && (SupportHyperplanes.nr_of_rows()!=0 ||inhomogeneous)) {1352if (verbose) {1353verboseOutput() << "Computing extreme rays as support hyperplanes of the dual cone:" << endl;1354}13551356compute_generators_inner<Number>();13571358}1359assert(isComputed(ConeProperty::Generators));1360}13611362template<typename Number>1363template<typename NumberFC>1364void Cone<Number>::compute_generators_inner() {13651366Matrix<Number> Dual_Gen;1367Dual_Gen=BasisChangePointed.to_sublattice_dual(SupportHyperplanes);1368// first we take the quotient of the efficient sublattice modulo the maximal subspace1369Sublattice_Representation<Number> Pointed(Dual_Gen,true); // sublattice of the dual space13701371// now we get the basis of the maximal subspace1372if(!isComputed(ConeProperty::MaximalSubspace)){1373BasisMaxSubspace = BasisChangePointed.from_sublattice(Pointed.getEquationsMatrix());1374BasisMaxSubspace.simplify_rows();1375// check_vanishing_of_grading_and_dehom();1376is_Computed.set(ConeProperty::MaximalSubspace);1377}1378if(!isComputed(ConeProperty::IsPointed)){1379pointed = (BasisMaxSubspace.nr_of_rows() == 0);1380is_Computed.set(ConeProperty::IsPointed);1381}1382BasisChangePointed.compose_dual(Pointed); // primal cone now pointed, may not yet be full dimensional13831384// restrict the supphyps to efficient sublattice and push to quotient mod subspace1385Matrix<NumberFC> Dual_Gen_Pointed;1386BasisChangePointed.convert_to_sublattice_dual(Dual_Gen_Pointed, SupportHyperplanes);1387Full_Cone<NumberFC> Dual_Cone(Dual_Gen_Pointed);1388Dual_Cone.verbose=verbose;1389Dual_Cone.do_extreme_rays=true; // we try to find them, need not exist1390try {1391Dual_Cone.dualize_cone();1392} catch(const NonpointedException& ){}; // we don't mind if the dual cone is not pointed13931394if (Dual_Cone.isComputed(ConeProperty::SupportHyperplanes)) {1395//get the extreme rays of the primal cone1396BasisChangePointed.convert_from_sublattice(Generators,1397Dual_Cone.getSupportHyperplanes());1398is_Computed.set(ConeProperty::Generators);13991400//get minmal set of support_hyperplanes if possible1401if (Dual_Cone.isComputed(ConeProperty::ExtremeRays)) {1402Matrix<NumberFC> Supp_Hyp = Dual_Cone.getGenerators().submatrix(Dual_Cone.getExtremeRays());1403BasisChangePointed.convert_from_sublattice_dual(SupportHyperplanes, Supp_Hyp);1404SupportHyperplanes.sort_lex();1405is_Computed.set(ConeProperty::SupportHyperplanes);1406}14071408// now the final transformations1409// only necessary if the basis changes computed so far do not make the cone full-dimensional1410// this is equaivalent to the dual cone bot being pointed1411if(!(Dual_Cone.isComputed(ConeProperty::IsPointed) && Dual_Cone.isPointed())){1412// first to full-dimensional pointed1413Matrix<Number> Help;1414Help=BasisChangePointed.to_sublattice(Generators); // sublattice of the primal space1415Sublattice_Representation<Number> PointedHelp(Help,true);1416BasisChangePointed.compose(PointedHelp);1417// second to efficient sublattice1418if(BasisMaxSubspace.nr_of_rows()==0){ // primal cone is pointed and we can copy1419BasisChange=BasisChangePointed;1420}1421else{1422Help=BasisChange.to_sublattice(Generators);1423Help.append(BasisChange.to_sublattice(BasisMaxSubspace));1424Sublattice_Representation<Number> EmbHelp(Help,true); // sublattice of the primal space1425compose_basis_change(EmbHelp);1426}1427}1428is_Computed.set(ConeProperty::Sublattice); // will not be changed anymore14291430setWeights();1431set_extreme_rays(vector<bool>(Generators.nr_of_rows(),true)); // here since they get sorted1432is_Computed.set(ConeProperty::ExtremeRays);1433}1434}14351436template<typename Number>1437vector<Sublattice_Representation<Number> > MakeSubAndQuot(const Matrix<Number>& Gen,1438const Matrix<Number>& Ker){1439vector<Sublattice_Representation<Number> > Result;1440Matrix<Number> Help=Gen;1441Help.append(Ker);1442Sublattice_Representation<Number> Sub(Help,true);1443Sublattice_Representation<Number> Quot=Sub;1444if(Ker.nr_of_rows()>0){1445Matrix<Number> HelpQuot=Sub.to_sublattice(Ker).kernel(); // kernel here to be interpreted as subspace of the dual1446// namely the linear forms vanishing on Ker1447Sublattice_Representation<Number> SubToQuot(HelpQuot,true); // sublattice of the dual1448Quot.compose_dual(SubToQuot);1449}1450Result.push_back(Sub);1451Result.push_back(Quot);14521453return Result;1454}14551456//---------------------------------------------------------------------------14571458template<typename Number>1459template<typename NumberFC>1460void Cone<Number>::extract_data(Full_Cone<NumberFC>& FC) {1461//this function extracts ALL available data from the Full_Cone1462//even if it was in Cone already <- this may change1463//it is possible to delete the data in Full_Cone after extracting it14641465if(verbose) {1466verboseOutput() << "transforming data..."<<flush;1467}14681469if (FC.isComputed(ConeProperty::Generators)) {1470BasisChangePointed.convert_from_sublattice(Generators,FC.getGenerators());1471is_Computed.set(ConeProperty::Generators);1472}14731474if (FC.isComputed(ConeProperty::IsPointed) && !isComputed(ConeProperty::IsPointed)) {1475pointed = FC.isPointed();1476if(pointed)1477is_Computed.set(ConeProperty::MaximalSubspace);1478is_Computed.set(ConeProperty::IsPointed);1479}148014811482if (FC.isComputed(ConeProperty::ExtremeRays)) {1483set_extreme_rays(FC.getExtremeRays());1484}1485if (FC.isComputed(ConeProperty::SupportHyperplanes)) {1486/* if (inhomogeneous) {1487// remove irrelevant support hyperplane 0 ... 0 11488vector<NumberFC> irr_hyp_subl;1489BasisChangePointed.convert_to_sublattice_dual(irr_hyp_subl, Dehomogenization);1490FC.Support_Hyperplanes.remove_row(irr_hyp_subl);1491} */1492// BasisChangePointed.convert_from_sublattice_dual(SupportHyperplanes, FC.getSupportHyperplanes());1493extract_supphyps(FC);1494if(inhomogeneous && FC.dim<dim){ // make inequality for the inhomogeneous variable appear as dehomogenization1495vector<Number> dehom_restricted=BasisChangePointed.to_sublattice_dual(Dehomogenization);1496for(size_t i=0;i<SupportHyperplanes.nr_of_rows();++i){1497if(dehom_restricted==BasisChangePointed.to_sublattice_dual(SupportHyperplanes[i])){1498SupportHyperplanes[i]=Dehomogenization;1499break;1500}1501}1502}1503SupportHyperplanes.sort_lex();1504is_Computed.set(ConeProperty::SupportHyperplanes);1505}1506if (FC.isComputed(ConeProperty::TriangulationSize)) {1507TriangulationSize = FC.totalNrSimplices;1508triangulation_is_nested = FC.triangulation_is_nested;1509triangulation_is_partial= FC.triangulation_is_partial;1510is_Computed.set(ConeProperty::TriangulationSize);1511is_Computed.set(ConeProperty::IsTriangulationPartial);1512is_Computed.set(ConeProperty::IsTriangulationNested);1513is_Computed.reset(ConeProperty::Triangulation);1514Triangulation.clear();1515}1516if (FC.isComputed(ConeProperty::TriangulationDetSum)) {1517convert(TriangulationDetSum, FC.detSum);1518is_Computed.set(ConeProperty::TriangulationDetSum);1519}15201521if (FC.isComputed(ConeProperty::Triangulation)) {1522size_t tri_size = FC.Triangulation.size();1523Triangulation = vector< pair<vector<key_t>, Number> >(tri_size);1524if(FC.isComputed(ConeProperty::ConeDecomposition))1525OpenFacets.resize(tri_size);1526SHORTSIMPLEX<NumberFC> simp;1527for (size_t i = 0; i<tri_size; ++i) {1528simp = FC.Triangulation.front();1529Triangulation[i].first.swap(simp.key);1530// sort(Triangulation[i].first.begin(), Triangulation[i].first.end());1531if (FC.isComputed(ConeProperty::TriangulationDetSum))1532convert(Triangulation[i].second, simp.vol);1533else1534Triangulation[i].second = 0;1535if(FC.isComputed(ConeProperty::ConeDecomposition))1536OpenFacets[i].swap(simp.Excluded);1537FC.Triangulation.pop_front();1538}1539if(FC.isComputed(ConeProperty::ConeDecomposition))1540is_Computed.set(ConeProperty::ConeDecomposition);1541is_Computed.set(ConeProperty::Triangulation);1542}15431544if (FC.isComputed(ConeProperty::RecessionRank) && isComputed(ConeProperty::MaximalSubspace)) {1545recession_rank = FC.level0_dim+BasisMaxSubspace.nr_of_rows();1546is_Computed.set(ConeProperty::RecessionRank);1547if (getRank() == recession_rank) {1548affine_dim = -1;1549} else {1550affine_dim = getRank()-1;1551}1552is_Computed.set(ConeProperty::AffineDim);1553}15541555/* if (FC.isComputed(ConeProperty::MaximalSubspace) &&1556!isComputed(ConeProperty::MaximalSubspace)) {1557BasisChangePointed.convert_from_sublattice(BasisMaxSubspace, FC.Basis_Max_Subspace);1558check_vanishing_of_grading_and_dehom();1559is_Computed.set(ConeProperty::MaximalSubspace);1560}*/15611562if (verbose) {1563verboseOutput() << " done." <<endl;1564}1565}15661567//---------------------------------------------------------------------------1568template<typename Number>1569template<typename NumberFC>1570void Cone<Number>::extract_supphyps(Full_Cone<NumberFC>& FC) {1571BasisChangePointed.convert_from_sublattice_dual(SupportHyperplanes, FC.getSupportHyperplanes());1572}15731574template<typename Number>1575void Cone<Number>::extract_supphyps(Full_Cone<Number>& FC) {1576if(BasisChangePointed.IsIdentity())1577swap(SupportHyperplanes,FC.Support_Hyperplanes);1578else1579SupportHyperplanes=BasisChangePointed.from_sublattice_dual(FC.getSupportHyperplanes());1580}15811582//---------------------------------------------------------------------------15831584template<typename Number>1585void Cone<Number>::set_extreme_rays(const vector<bool>& ext) {1586assert(ext.size() == Generators.nr_of_rows());1587ExtremeRaysIndicator=ext;1588vector<bool> choice=ext;1589if (inhomogeneous) {1590// separate extreme rays to rays of the level 0 cone1591// and the verticies of the polyhedron, which are in level >=11592size_t nr_gen = Generators.nr_of_rows();1593vector<bool> VOP(nr_gen);1594for (size_t i=0; i<nr_gen; i++) {1595if (ext[i] && v_scalar_product(Generators[i],Dehomogenization) != 0) {1596VOP[i] = true;1597choice[i]=false;1598}1599}1600VerticesOfPolyhedron=Generators.submatrix(VOP);1601VerticesOfPolyhedron.simplify_rows();1602VerticesOfPolyhedron.sort_by_weights(WeightsGrad,GradAbs);1603is_Computed.set(ConeProperty::VerticesOfPolyhedron);1604}1605ExtremeRays=Generators.submatrix(choice);1606ExtremeRays.simplify_rows();1607if(inhomogeneous && !isComputed(ConeProperty::AffineDim) && isComputed(ConeProperty::MaximalSubspace)){1608size_t level0_dim=ExtremeRays.max_rank_submatrix_lex().size();1609recession_rank = level0_dim+BasisMaxSubspace.nr_of_rows();1610is_Computed.set(ConeProperty::RecessionRank);1611if (getRank() == recession_rank) {1612affine_dim = -1;1613} else {1614affine_dim = getRank()-1;1615}1616is_Computed.set(ConeProperty::AffineDim);16171618}1619ExtremeRays.sort_by_weights(WeightsGrad,GradAbs);1620is_Computed.set(ConeProperty::ExtremeRays);1621}16221623//---------------------------------------------------------------------------16241625template<typename Number>1626void Cone<Number>::complete_sublattice_comp(ConeProperties& ToCompute) {16271628if(!isComputed(ConeProperty::Sublattice))1629return;1630is_Computed.set(ConeProperty::Rank);1631if(ToCompute.test(ConeProperty::Equations)){1632BasisChange.getEquationsMatrix(); // just to force computation, ditto below1633is_Computed.set(ConeProperty::Equations);1634}1635/*1636if(ToCompute.test(ConeProperty::Congruences) || ToCompute.test(ConeProperty::ExternalIndex)){1637// BasisChange.getCongruencesMatrix();1638BasisChange.getExternalIndex();1639// is_Computed.set(ConeProperty::Congruences);1640// is_Computed.set(ConeProperty::ExternalIndex);1641}*/1642}164316441645template<typename Number>1646Cone<Number>::~Cone() {1647}1648164916501651} // end namespace libQnormaliz165216531654