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//---------------------------------------------------------------------------2425#include <algorithm>26#include <sstream>27#include <math.h>28#include "libnormaliz/integer.h"29#include "libnormaliz/vector_operations.h"3031//---------------------------------------------------------------------------3233namespace libnormaliz {34using namespace std;3536bool try_convert(long& ret, const long long& val) {37if (fits_long_range(val)) {38ret = val;39return true;40}41return false;42}4344bool try_convert(long& ret, const mpz_class& val) {45if (!val.fits_slong_p()) {46return false;47}48ret = val.get_si();49return true;50}5152bool try_convert(long long& ret, const mpz_class& val) {53if (val.fits_slong_p()) {54ret = val.get_si();55return true;56}57if (sizeof(long long)==sizeof(long)) {58return false;59}60mpz_class quot;61ret = mpz_fdiv_q_ui(quot.get_mpz_t(), val.get_mpz_t(), LONG_MAX); //returns remainder62if (!quot.fits_slong_p()){63return false;64}65ret += ((long long) quot.get_si())*((long long) LONG_MAX);66return true;67}6869bool try_convert(mpz_class& ret, const long long& val) {70if (fits_long_range(val)) {71ret = mpz_class(long(val));72} else {73ret = mpz_class(long (val % LONG_MAX)) + mpz_class(LONG_MAX) * mpz_class(long(val/LONG_MAX));74}75return true;76}7778bool fits_long_range(long long a) {79return sizeof(long long) == sizeof(long) || (a <= LONG_MAX && a >= LONG_MIN);80}8182template<typename FromType>83bool try_convert(nmz_float& ret, const FromType& val){84ret= (nmz_float) val;85return true;86}8788bool try_convert(nmz_float& ret, const mpz_class& val){89ret=val.get_d();90return true;91}9293template<typename ToType>94bool try_convert(ToType& ret, const nmz_float& val){95mpz_class bridge;96if(!try_convert(bridge,val))97return false;98return try_convert(ret,bridge);99}100101bool try_convert(mpz_class& ret, const nmz_float& val){102ret=mpz_class(val);103return true;104}105106//---------------------------------------------------------------------------107108template <typename Integer>109Integer gcd(const Integer& a, const Integer& b){110if (a==0) {111return Iabs<Integer>(b);112}113if (b==0) {114return Iabs<Integer>(a);115}116Integer q0,q1,r;117q0=Iabs<Integer>(a);118r=Iabs<Integer>(b);119do {120q1=r;121r=q0%q1;122q0=q1;123} while (r!=0);124return q1;125}126127template<> mpz_class gcd<mpz_class>(const mpz_class& a, const mpz_class& b) {128mpz_class g;129mpz_gcd (g.get_mpz_t(), a.get_mpz_t(), b.get_mpz_t());130return g;131}132133template void sign_adjust_and_minimize<long long>(const long long& a, const long long& b, long long& d, long long& u, long long&v);134template long long ext_gcd<long long>(const long long& a, const long long& b, long long& u, long long&v);135136137template <typename Integer>138void sign_adjust_and_minimize(const Integer& a, const Integer& b, Integer& d, Integer& u, Integer&v){139if(d<0){140d=-d;141u=-u;142v=-v;143}144// cout << u << " " << v << endl;145if(b==0)146return;147148Integer sign=1;149if(a<0)150sign=-1;151Integer u1= (sign*u) % (Iabs(b)/d);152if(u1==0)153u1+=Iabs(b)/d;154u=sign*u1;155v=(d-a*u)/b;156}157158159template <typename Integer>160Integer ext_gcd(const Integer& a, const Integer& b, Integer& u, Integer&v){161162u=1;163v=0;164Integer d=a;165if (b==0) {166sign_adjust_and_minimize(a,b,d,u,v);167return(d);168}169Integer v1=0;170Integer v3=b;171Integer q,t1,t3;172while(v3!=0){173q=d/v3;174t3=d-q*v3;175t1=u-q*v1;176u=v1;177d=v3;178v1=t1;179v3=t3;180}181sign_adjust_and_minimize(a,b,d,u,v);182return(d);183}184185//---------------------------------------------------------------------------186187template <typename Integer>188Integer lcm(const Integer& a, const Integer& b){189if ((a==0)||(b==0)) {190return 0;191}192else193return Iabs<Integer>(a*b/gcd<Integer>(a,b));194}195196template<> mpz_class lcm<mpz_class>(const mpz_class& a, const mpz_class& b) {197mpz_class g;198mpz_lcm (g.get_mpz_t(), a.get_mpz_t(), b.get_mpz_t());199return g;200}201202//---------------------------------------------------------------------------203204template <typename Integer>205size_t decimal_length(Integer a){206ostringstream test;207test << a;208return test.str().size();209}210211//---------------------------------------------------------------------------212213template <typename Integer>214Integer permutations(const size_t& a, const size_t& b){215unsigned long i;216Integer P=1;217for (i = a+1; i <= b; i++) {218P*=i;219}220return P;221}222223//---------------------------------------------------------------------------224225template<typename Integer>226Integer permutations_modulo(const size_t& a, const size_t& b, long m) {227unsigned long i;228Integer P=1;229for (i = a+1; i <= b; i++) {230P*=i; P%=m;231}232return P;233}234//---------------------------------------------------------------------------235236template<typename Integer>237Integer int_max_value_dual(){238Integer k=sizeof(Integer)*8-2; // number of bytes convetred to number of bits239Integer test=1;240test = test << k; // (maximal positive number)/2^k241return test;242}243244//---------------------------------------------------------------------------245246template<typename Integer>247Integer int_max_value_primary(){248Integer k=sizeof(Integer)*8-12; // number of bytes convetred to number of bits249Integer test=1;250test = test << k; // (maximal positive number)/2^k251// test=0; // 10000;252return test;253}254255//---------------------------------------------------------------------------256257template<>258mpz_class int_max_value_dual<mpz_class>(){259assert(false);260return 0;261}262263//---------------------------------------------------------------------------264265template<>266mpz_class int_max_value_primary<mpz_class>(){267assert(false);268return 0;269}270271272//---------------------------------------------------------------------------273274template<typename Integer>275void check_range_list(const CandidateList<Integer>& ll){276check_range_list(ll.Candidates);277}278279//---------------------------------------------------------------------------280281template<typename Integer>282void check_range_list(const std::list<Candidate<Integer> >& ll){283284if (using_GMP<Integer>())285return;286287typename list<Candidate<Integer> >::const_iterator v=ll.begin();288289Integer test=int_max_value_dual<Integer>();290// cout << "test " << test << endl;291292for(;v!=ll.end();++v){293for(size_t i=0;i<v->values.size();++i)294if(Iabs(v->values[i])>= test){295// cout << *v;296// cout << "i " << i << " " << Iabs((*v)[i]) << endl;297throw ArithmeticException("Vector entry out of range. Imminent danger of arithmetic overflow.");298}299300}301302303}304305//---------------------------------------------------------------------------306template<typename Integer>307void minimal_remainder(const Integer& a, const Integer&b, Integer& quot, Integer& rem) {308309quot=a/b;310rem=a-quot*b;311if(rem==0)312return;313if(2*Iabs(rem)>Iabs(b)){314if((rem<0 && b>0) || (rem >0 && b<0)){315rem+=b;316quot--;317}318else{319rem-=b;320quot++;321}322}323}324325//---------------------------------------------------------------------------326327mpq_class dec_fraction_to_mpq(string s){328329// cout << "s " << s <<endl;330331mpz_class sign=1;332if(s[0]=='+')333s=s.substr(1);334else335if(s[0]=='-'){336s=s.substr(1);337sign=-1;338}339340if(s[0]=='+' || s[0]=='-')341throw BadInputException("Error in decimal fraction");342343string int_string,frac_string,exp_string;344size_t frac_part_length=0;345size_t pos_point=s.find(".");346size_t pos_E=s.find("e");347if(pos_point!=string::npos){348int_string=s.substr(0,pos_point);349if(pos_E!=string::npos){350frac_part_length=pos_E-(pos_point+1);351}352else353frac_part_length=s.size()-(pos_point+1);354frac_string=s.substr(pos_point+1,frac_part_length);355if(frac_string[0]=='+' || frac_string[0]=='-')356throw BadInputException("Error in decimal fraction");357}358else359int_string=s.substr(0,pos_E);360if(pos_E!=string::npos)361exp_string=s.substr(pos_E+1,s.size()-(pos_E+1));362363/* cout << "int " << int_string << endl;364cout << "frac " << frac_string << endl;365cout << "exp " << exp_string << endl; */366367// remove leading 0368while(int_string[0]=='0')369int_string=int_string.substr(1);370while(frac_string[0]=='0')371frac_string=frac_string.substr(1);372373mpq_class int_part, frac_part, exp_part;374if(!int_string.empty())375int_part=mpz_class(int_string);376377if(pos_E==0)378int_part=1;379380// cout << "int_part " << int_part << endl;381382mpz_class den=1;383if(!frac_string.empty()){384frac_part=mpz_class(frac_string);385for(size_t i=0;i<frac_part_length;++i)386den*=10;387}388// cout << "frac_part " << frac_part << endl;389mpq_class result=int_part;390if(frac_part!=0)391result+=frac_part/den;392if(!exp_string.empty()){393long expo=stol(exp_string);394long abs_expo=Iabs(expo);395// cout << "expo " << expo << endl;396mpz_class factor=1;397for(long i=0;i< abs_expo;++i)398factor*=10;399if(expo>=0)400result*=factor;401else402result/=factor;403}404/* cout <<" result " << sign*result << endl;405cout << "==========" << endl; */406return sign*result;407}408409//----------------------------------------------------------------------410// the next function produce an integer quotient and determine whether411// there is a remainder412413bool int_quotient(long& Quot, const long long& Num, const long& Den){414415Quot=Iabs(Num)/Iabs(Den);416return Quot*Iabs(Den)!=Iabs(Num);417}418419bool int_quotient(long long& Quot, const long& Num, const long& Den){420421Quot=Iabs(Num)/Iabs(Den);422return Quot*Iabs(Den)!=Iabs(Num);423}424425426bool int_quotient(mpz_class& Quot, const mpz_class& Num, const mpz_class& Den){427428Quot=Iabs(Num)/Iabs(Den);429return Quot*Iabs(Den)!=Iabs(Num);430}431432template<typename IntegerRet>433bool int_quotient(IntegerRet& Quot, const nmz_float& Num, const nmz_float& Den){434435nmz_float FloatQuot=Iabs(Num)/Iabs(Den); // cout << "FF " << FloatQuot << endl;436nmz_float IntQuot=trunc(FloatQuot+nmz_epsilon); // cout << "II " << IntQuot << endl;437Quot=convertTo<IntegerRet>(IntQuot); // cout << "QQ " << Quot << endl;438return FloatQuot-IntQuot > nmz_epsilon;439}440441442} //end namespace libnormaliz443444445