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: 418386/*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 <iostream>24#include <cctype> // std::isdigit25#include <limits> // numeric_limits2627#include "Qoptions.h"28#include "libQnormaliz/libQnormaliz.h"29#include "libQnormaliz/Qmap_operations.h"30#include "libQnormaliz/Qcone_property.h"3132// eats up a comment, stream must start with "/*", eats everything until "*/"33void skip_comment(istream& in) {34int i = in.get();35int j = in.get();36if (i != '/' || j != '*') {37throw BadInputException("Bad comment start!");38}39while (in.good()) {40in.ignore(numeric_limits<streamsize>::max(), '*'); //ignore everything until next '*'41i = in.get();42if (in.good() && i == '/') return; // successfully skipped comment43}44throw BadInputException("Incomplete comment!");45}4647template<typename Number>48void save_matrix(map<Type::InputType, vector<vector<Number> > >& input_map,49InputType input_type, const vector<vector<Number> >& M) {50//check if this type already exists51if (exists_element(input_map, input_type)) {52/*throw BadInputException("Multiple inputs of type \"" + type_string53+ "\" are not allowed!");*/54input_map[input_type].insert(input_map[input_type].end(),M.begin(),M.end());55return;56}57input_map[input_type] = M;58}5960template<typename Number>61void save_empty_matrix(map<Type::InputType, vector<vector<Number> > >& input_map,62InputType input_type){6364vector<vector<Number> > M;65save_matrix(input_map, input_type, M);66}6768template <typename Number>69vector<vector<Number> > transpose_mat(const vector<vector<Number> >& mat){7071if(mat.size()==0 || mat[0].size()==0)72return vector<vector<Number> >(0);73size_t m=mat[0].size();74size_t n=mat.size();75vector<vector<Number> > transpose(m,vector<Number> (n,0));76for(size_t i=0;i<m;++i)77for(size_t j=0;j<n;++j)78transpose[i][j]=mat[j][i];79return transpose;80}8182template <typename Number>83void append_row(const vector<Number> row, map <Type::InputType, vector< vector<Number> > >& input_map,84Type::InputType input_type) {8586vector<vector<Number> > one_row(1,row);87save_matrix(input_map,input_type,one_row);88}8990template <typename Number>91void process_constraint(const string& rel, const vector<Number>& left, Number right, const Number modulus,92map <Type::InputType, vector< vector<Number> > >& input_map, bool forced_hom) {9394vector<Number> row=left;95bool inhomogeneous=false;96if(right!=0 || rel=="<" || rel==">")97inhomogeneous=true;98string modified_rel=rel;99bool strict_inequality=false;100if(rel=="<"){101strict_inequality=true;102right-=1;103modified_rel="<=";104105}106if(rel==">"){107strict_inequality=true;108right+=1;109modified_rel=">=";110}111if(strict_inequality && forced_hom){112throw BadInputException("Strict inequality not allowed in hom_constraints!");113}114if(inhomogeneous || forced_hom)115row.push_back(-right); // rhs --> lhs116if(modified_rel=="<="){ // convert <= to >=117for(size_t j=0; j<row.size();++j)118row[j]=-row[j];119modified_rel=">=";120}121if(rel=="~")122row.push_back(modulus);123124if(inhomogeneous && !forced_hom){125if(modified_rel=="="){126append_row(row,input_map,Type::inhom_equations);127return;128}129if(modified_rel==">="){130append_row(row,input_map,Type::inhom_inequalities);131return;132}133if(modified_rel=="~"){134append_row(row,input_map,Type::inhom_congruences);135return;136}137}138else {139if(modified_rel=="="){140append_row(row,input_map,Type::equations);141return;142}143if(modified_rel==">="){144append_row(row,input_map,Type::inequalities);145return;146}147if(modified_rel=="~"){148append_row(row,input_map,Type::congruences);149return;150}151}152throw BadInputException("Illegal constrint type "+rel+" !");153}154155template <typename Number>156bool read_modulus(istream& in, Number& modulus) {157158in >> std::ws; // gobble any leading white space159char dummy;160in >> dummy;161if(dummy != '(')162return false;163in >> modulus;164if(in.fail() || modulus==0)165return false;166in >> std::ws; // gobble any white space before closing167in >> dummy;168if(dummy != ')')169return false;170return true;171}172173template <typename Number>174void read_constraints(istream& in, long dim, map <Type::InputType, vector< vector<Number> > >& input_map, bool forced_hom) {175176long nr_constraints;177in >> nr_constraints;178179if(in.fail() || nr_constraints < 0) {180throw BadInputException("Cannot read "181+ toString(nr_constraints) + " constraints!");182}183long hom_correction=0;184if(forced_hom)185hom_correction=1;186for(long i=0;i< nr_constraints; ++i) {187vector<Number> left(dim-hom_correction);188for(long j=0;j<dim-hom_correction;++j){189in >> left[j];190}191string rel, modulus_str;192Number right, modulus=0;193in >> rel;194in >> right;195if(rel=="~") {196if(!read_modulus(in,modulus))197throw BadInputException("Error while reading modulus of congruence!");198}199if (in.fail()) {200throw BadInputException("Error while reading constraint!");201}202process_constraint(rel,left,right,modulus,input_map,forced_hom);203}204}205206template <typename Number>207bool read_sparse_vector(istream& in, vector<Number>& input_vec, long length){208209input_vec=vector<Number> (length,0);210char dummy;211212while(true){213in >> std::ws;214int c = in.peek();215if(c==';'){216in >> dummy; // swallow ;217return true;218}219long pos;220in >> pos;221if(in.fail())222return false;223pos--;224if(pos<0 or pos>=length)225return false;226in >> std::ws;227c=in.peek();228if(c!=':')229return false;230in >> dummy; // skip :231Number value;232in >> value;233if(in.fail())234return false;235input_vec[pos]=value;236}237}238239template <typename Number>240bool read_formatted_vector(istream& in, vector<Number>& input_vec) {241242input_vec.clear();243in >> std::ws;244char dummy;245in >> dummy; // read first proper character246if(dummy!='[')247return false;248bool one_more_entry_required=false;249while(true){250in >> std::ws;251if(!one_more_entry_required && in.peek()==']'){252in >> dummy;253return true;254}255Number number;256in >> number;257if(in.fail())258return false;259input_vec.push_back(number);260in >> std::ws;261one_more_entry_required=false;262if(in.peek()==',' || in.peek()==';'){ // skip potential separator263in >> dummy;264one_more_entry_required=true;265}266}267}268269template <typename Number>270bool read_formatted_matrix(istream& in, vector<vector<Number> >& input_mat, bool transpose) {271input_mat.clear();272in >> std::ws;273char dummy;274in >> dummy; // read first proper character275if(dummy!='[')276return false;277bool one_more_entry_required=false;278while(true){279in >> std::ws;280if(!one_more_entry_required && in.peek()==']'){ // closing ] found281in >> dummy;282if(transpose)283input_mat=transpose_mat(input_mat);284return true;285}286vector<Number> input_vec;287if(!read_formatted_vector(in,input_vec)){288throw BadInputException("Error in reading input vector!");289}290if(input_mat.size()>0 && input_vec.size()!=input_mat[0].size()){291throw BadInputException("Rows of input matrix have unequal lengths!");292}293input_mat.push_back(input_vec);294in >> std::ws;295one_more_entry_required=false;296if(in.peek()==',' || in.peek()==';'){ // skip potential separator297in >> dummy;298one_more_entry_required=true;299}300}301}302303304template <typename Number>305map <Type::InputType, vector< vector<Number> > > readNormalizInput (istream& in, OptionsHandler& options) {306307string type_string;308long i,j;309long nr_rows,nr_columns,nr_rows_or_columns;310InputType input_type;311Number number;312ConeProperty::Enum cp;313314map<Type::InputType, vector< vector<Number> > > input_map;315typename map<Type::InputType, vector< vector<Number> > >::iterator it;316317in >> std::ws; // eat up any leading white spaces318int c = in.peek();319if ( c == EOF ) {320throw BadInputException("Empty input file!");321}322bool new_input_syntax = !std::isdigit(c);323324if (new_input_syntax) {325long dim;326while (in.peek() == '/') {327skip_comment(in);328in >> std::ws;329}330in >> type_string;331if (!in.good() || type_string != "amb_space") {332throw BadInputException("First entry must be \"amb_space\"!");333}334bool dim_known=false;335in >> std::ws;336c=in.peek();337if(c=='a'){338string dummy;339in >> dummy;340if(dummy!="auto"){341throw BadInputException("Bad amb_space value!");342}343}344else{345in >> dim;346if (!in.good() || dim <= 0) {347throw BadInputException("Bad amb_space value!");348}349dim_known=true;350}351while (in.good()) { //main loop352353bool transpose=false;354in >> std::ws; // eat up any leading white spaces355c = in.peek();356if (c == EOF) break;357if (c == '/') {358skip_comment(in);359} else {360in >> type_string;361if (in.fail()) {362throw BadInputException("Could not read type string!");363}364if (std::isdigit(c)) {365throw BadInputException("Unexpected number " + type_string366+ " when expecting a type!");367}368if (isConeProperty(cp, type_string)) {369options.activateInputFileConeProperty(cp);370continue;371}372/* if (type_string == "BigInt") {373options.activateInputFileBigInt();374continue;375} */376if (type_string == "LongLong") {377options.activateInputFileLongLong();378continue;379}380if (type_string == "total_degree") {381if(!dim_known){382throw BadInputException("Ambient space must be known for "+type_string+"!");383}384input_type = Type::grading;385save_matrix(input_map, input_type, vector< vector<Number> >(1,vector<Number>(dim+type_nr_columns_correction(input_type),1)));386continue;387}388if (type_string == "nonnegative") {389if(!dim_known){390throw BadInputException("Ambient space must be known for "+type_string+"!");391}392input_type = Type::signs;393save_matrix(input_map, input_type, vector< vector<Number> >(1,vector<Number>(dim+type_nr_columns_correction(input_type),1)));394continue;395}396if(type_string == "constraints") {397if(!dim_known){398throw BadInputException("Ambient space must be known for "+type_string+"!");399}400read_constraints(in,dim,input_map,false);401continue;402}403if(type_string == "hom_constraints") {404if(!dim_known){405throw BadInputException("Ambient space must be known for "+type_string+"!");406}407read_constraints(in,dim,input_map,true);408continue;409}410411412input_type = to_type(type_string);413if(dim_known)414nr_columns = dim + type_nr_columns_correction(input_type);415416if (type_is_vector(input_type)) {417nr_rows_or_columns = nr_rows = 1;418in >> std::ws; // eat up any leading white spaces419c = in.peek();420if (c=='u') { // must be unit vector421string vec_kind;422in >> vec_kind;423if (vec_kind != "unit_vector") {424throw BadInputException("Error while reading "425+ type_string426+ ": unit_vector expected!");427}428429long pos = 0;430in >> pos;431if (in.fail()) {432throw BadInputException("Error while reading "433+ type_string434+ " as a unit_vector!");435}436437if(!dim_known){438throw BadInputException("Ambient space must be known for unit vector "+type_string+"!");439}440441vector< vector<Number> > e_i = vector< vector<Number> >(1,vector<Number>(nr_columns,0));442if (pos < 1 || pos > static_cast<long>(e_i[0].size())) {443throw BadInputException("Error while reading "444+ type_string + " as a unit_vector "445+ toString(pos) + "!");446}447pos--; // in input file counting starts from 1448e_i[0].at(pos) = 1;449save_matrix(input_map, input_type, e_i);450continue;451} // end unit vector452453if(c=='s'){ // must be "sparse"454string vec_kind;455in >> vec_kind;456if (vec_kind != "sparse") {457throw BadInputException("Error while reading "458+ type_string459+ ": sparse vector expected!");460}461462if(!dim_known){463throw BadInputException("Ambient space must be known for sparse vector "+type_string+"!");464}465466vector<Number> sparse_vec;467nr_columns = dim + type_nr_columns_correction(input_type);468bool success = read_sparse_vector(in,sparse_vec,nr_columns);469if(!success){470throw BadInputException("Error while reading "471+ type_string472+ " as a sparse vector!");473}474save_matrix(input_map, input_type, vector<vector<Number> > (1,sparse_vec));475continue;476}477478if (c == '[') { // must be formatted vector479vector<Number> formatted_vec;480bool success = read_formatted_vector(in,formatted_vec);481if(!dim_known){482dim=formatted_vec.size()- type_nr_columns_correction(input_type);483dim_known=true;484nr_columns = dim + type_nr_columns_correction(input_type);485}486if(!success || (long) formatted_vec.size()!=nr_columns){487throw BadInputException("Error while reading "488+ type_string489+ " as a formatted vector!");490}491save_matrix(input_map, input_type, vector<vector<Number> > (1,formatted_vec));492continue;493} // end formatted vector494495} else { // end vector, it is a matrix. Plain vector read as a one row matrix later on496in >> std::ws;497c = in.peek();498499if(c!='[' && !std::isdigit(c)){ // must be transpose500string transpose_str;501in >> transpose_str;502if(transpose_str!="transpose"){503throw BadInputException("Illegal keyword "+transpose_str+" following matrix type!");504}505transpose=true;506in >> std::ws;507c = in.peek();508}509if(c=='['){ // it is a formatted matrix510vector<vector<Number> > formatted_mat;511bool success=read_formatted_matrix(in,formatted_mat, transpose);512if(!success){513throw BadInputException("Error while reading formatted matrix "514+ type_string + "!");515}516if(formatted_mat.size() ==0){ // empty matrix517input_type = to_type(type_string);518save_empty_matrix(input_map, input_type);519continue;520}521if(!dim_known){522dim=formatted_mat[0].size()- type_nr_columns_correction(input_type);523dim_known=true;524nr_columns = dim + type_nr_columns_correction(input_type);525}526527if((long) formatted_mat[0].size()!=nr_columns){528throw BadInputException("Error while reading formatted matrix "529+ type_string + "!");530}531532save_matrix(input_map, input_type, formatted_mat);533continue;534} // only plain matrix left535536in >> nr_rows_or_columns; // is number of columns if transposed537nr_rows=nr_rows_or_columns; // most of the time538}539540if(!dim_known){541throw BadInputException("Ambient space must be known for plain matrix or vector "+type_string+"!");542}543544if(transpose)545swap(nr_rows,nr_columns);546547if(in.fail() || nr_rows_or_columns < 0) {548throw BadInputException("Error while reading "549+ type_string + " (a " + toString(nr_rows)550+ "x" + toString(nr_columns)551+ " matrix) !");552}553if(nr_rows==0){554input_type = to_type(type_string);555save_empty_matrix(input_map, input_type);556continue;557}558559vector< vector<Number> > M(nr_rows);560in >> std::ws;561c=in.peek();562if(c=='s'){ // must be sparse563string sparse_test;564in >> sparse_test;565if (sparse_test!= "sparse") {566throw BadInputException("Error while reading "567+ type_string568+ ": sparse matrix expected!");569}570for(long i=0;i<nr_rows;++i){571bool success=read_sparse_vector(in,M[i],nr_columns);572if(!success){573throw BadInputException("Error while reading "574+ type_string575+ ": corrupted sparse matrix");576}577578}579} else{ // dense matrix580for(i=0; i<nr_rows; i++){581M[i].resize(nr_columns);582for(j=0; j<nr_columns; j++) {583in >> M[i][j];584}585}586}587if(transpose)588M=transpose_mat(M);589save_matrix(input_map, input_type, M);590}591if (in.fail()) {592throw BadInputException("Error while reading " + type_string593+ " (a " + toString(nr_rows) + "x"594+ toString(nr_columns) + " matrix) !");595}596}597} else {598// old input syntax599while (in.good()) {600in >> nr_rows;601if(in.fail())602break;603in >> nr_columns;604if((nr_rows <0) || (nr_columns < 0)){605throw BadInputException("Error while reading a "606+ toString(nr_rows) + "x" + toString(nr_columns)607+ " matrix !");608}609vector< vector<Number> > M(nr_rows,vector<Number>(nr_columns));610for(i=0; i<nr_rows; i++){611for(j=0; j<nr_columns; j++) {612in >> number;613M[i][j] = number;614}615}616617in >> type_string;618619if ( in.fail() ) {620throw BadInputException("Error while reading a "621+ toString(nr_rows) + "x" + toString(nr_columns)622+ " matrix!");623}624625input_type = to_type(type_string);626627//check if this type already exists628save_matrix(input_map, input_type, M);629}630}631return input_map;632}633634635