|
@@ -0,0 +1,352 @@
|
|
|
+/**
|
|
|
+ * This file is part of Gomu.
|
|
|
+ *
|
|
|
+ * Copyright 2016 by Jean Fromentin <jean.fromentin@math.cnrs.fr>
|
|
|
+ *
|
|
|
+ * Gomu is free software: you can redistribute it and/or modify
|
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
|
+ * the Free Software Foundation, either version 3 of the License, or
|
|
|
+ * (at your option) any later version.
|
|
|
+ *
|
|
|
+ * Gomu is distributed in the hope that it will be useful,
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
+ * GNU General Public License for more details.
|
|
|
+ *
|
|
|
+ * You should have received a copy of the GNU General Public License
|
|
|
+ * along with Gomu. If not, see <http://www.gnu.org/licenses/>.
|
|
|
+ */
|
|
|
+
|
|
|
+#include "flint.hpp"
|
|
|
+
|
|
|
+string
|
|
|
+display(fmpz* z){
|
|
|
+ char* disp=fmpz_get_str(NULL,10,z);
|
|
|
+ string res="\033[34m";
|
|
|
+ res+=disp;
|
|
|
+ res+="\033[0m";
|
|
|
+ free(disp);
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+string
|
|
|
+display(fmpz_poly_struct* P){
|
|
|
+ slong len=fmpz_poly_length(P);
|
|
|
+ if(len==0) return "\033[34m0\033[0m";
|
|
|
+ if(len==1) return display(fmpz_poly_get_coeff_ptr(P,0));
|
|
|
+ string str;
|
|
|
+ fmpz_t temp;
|
|
|
+ fmpz_init(temp);
|
|
|
+ for(slong i=len-1;i>=0;--i){
|
|
|
+ fmpz* coeff=fmpz_poly_get_coeff_ptr(P,i);
|
|
|
+ int sgn=fmpz_sgn(coeff);
|
|
|
+ //Display coeff
|
|
|
+ if(i==len-1){
|
|
|
+ if(sgn==-1){
|
|
|
+ fmpz_neg(temp,coeff);
|
|
|
+ str+="\033[34m-\033[36m";
|
|
|
+ if(not fmpz_is_one(temp)){
|
|
|
+ str+=display(temp);
|
|
|
+ str+='.';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ if(not fmpz_is_one(coeff)){
|
|
|
+ str+=display(coeff);
|
|
|
+ str+='.';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ if(sgn==-1){
|
|
|
+ fmpz_neg(temp,coeff);
|
|
|
+ str+="\033[34m-\033[0m";
|
|
|
+ if(i==0) str+=display(temp);
|
|
|
+ else if(not fmpz_is_one(temp)){
|
|
|
+ str+=display(temp);
|
|
|
+ str+='.';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(sgn==1){
|
|
|
+ str+="\033[34m+\033[0m";
|
|
|
+ if(i==0) str+=display(coeff);
|
|
|
+ else if(not fmpz_is_one(coeff)){
|
|
|
+ str+=display(coeff);
|
|
|
+ str+='.';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(i>0 and not fmpz_is_zero(coeff)){
|
|
|
+ str+="x";
|
|
|
+ if(i>1){
|
|
|
+ str+="^\033[35m"+to_string(i)+"\033[0m";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ fmpz_clear(temp);
|
|
|
+ return str;
|
|
|
+}
|
|
|
+
|
|
|
+string display(fmpz_poly_factor_struct* F){
|
|
|
+ string str="";
|
|
|
+ if(not fmpz_is_one(&F->c)){
|
|
|
+ str+="\033[34m"+to_string(F->c)+"\033[0m.";
|
|
|
+ }
|
|
|
+ for(ulong i=0;i<(F->num);++i){
|
|
|
+ if(i!=0) str+='.';
|
|
|
+ fmpz_poly_struct* P=&F->p[i];
|
|
|
+ if(fmpz_is_zero(fmpz_poly_get_coeff_ptr(P,0))) str+=display(P);
|
|
|
+ else{
|
|
|
+ str+='(';
|
|
|
+ str+=display(P);
|
|
|
+ str+=')';
|
|
|
+ }
|
|
|
+ slong e=F->exp[i];
|
|
|
+ if(e!=1) str+="^\033[35m"+to_string(e)+"\033[0m";
|
|
|
+ }
|
|
|
+ return str;
|
|
|
+}
|
|
|
+
|
|
|
+string
|
|
|
+display(fmpz_poly_q_struct* R){
|
|
|
+ char* disp=fmpz_poly_q_get_str_pretty(R,"x");
|
|
|
+ string res=disp;
|
|
|
+ free(disp);
|
|
|
+ return res;
|
|
|
+}
|
|
|
+
|
|
|
+string
|
|
|
+display(fmpz_mat_struct* A){
|
|
|
+ char* disp;
|
|
|
+ string str;
|
|
|
+ for(ulong i=0;i<A->r;++i){
|
|
|
+ if(i!=0) str+='\n';
|
|
|
+ str+="\033[37m[\033[0m";
|
|
|
+ for(long j=0;j<A->c;++j){
|
|
|
+ if(j!=0) str+=' ';
|
|
|
+ str+=display(get(A,i,j));
|
|
|
+ }
|
|
|
+ str+="\033[37m]\033[0m";
|
|
|
+ }
|
|
|
+ return str;
|
|
|
+}
|
|
|
+
|
|
|
+string
|
|
|
+display(fmpz_poly_mat_struct* A){
|
|
|
+ string str;
|
|
|
+ for(ulong i=0;i<A->r;++i){
|
|
|
+ if(i!=0) str+='\n';
|
|
|
+ str+='[';
|
|
|
+ for(ulong j=0;j<A->c;++j){
|
|
|
+ if(j!=0) str+=' ';
|
|
|
+ str+=" "+display(get(A,i,j));
|
|
|
+ }
|
|
|
+ str+=']';
|
|
|
+ }
|
|
|
+ return str;
|
|
|
+}
|
|
|
+
|
|
|
+ostream& operator<<(ostream& os,const fmpz_mat_t A){
|
|
|
+ if(A->c==1){
|
|
|
+ os<<'['<<get(A,0,0)<<']';
|
|
|
+ for(ulong i=1;i<A->r;++i) os<<endl<<'['<<get(A,i,0)<<']';
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ os<<'['<<get(A,0,0);
|
|
|
+ for(ulong j=1;j<A->c;++j) os<<' '<<get(A,0,j);
|
|
|
+ os<<']';
|
|
|
+ for(ulong i=1;i<A->r;++i){
|
|
|
+ os<<endl<<'['<<get(A,i,0);
|
|
|
+ for(ulong j=1;j<A->c;++j) os<<' '<<get(A,i,j);
|
|
|
+ os<<']';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return os;
|
|
|
+}
|
|
|
+
|
|
|
+ostream& operator<<(ostream& os,const fmpz_poly_factor_t F){
|
|
|
+ if(not fmpz_is_one(&F->c)) os<<F->c<<'.';
|
|
|
+ for(ulong i=0;i<(F->num);++i){
|
|
|
+ if(i!=0) os<<'.';
|
|
|
+ fmpz_poly_struct* P=&F->p[i];
|
|
|
+ if(fmpz_is_zero(fmpz_poly_get_coeff_ptr(P,0))) os<<&F->p[i];
|
|
|
+ else os<<'('<<&F->p[i]<<')';
|
|
|
+ slong e=F->exp[i];
|
|
|
+ if(e!=1) os<<'^'<<e;
|
|
|
+ }
|
|
|
+ return os;
|
|
|
+}
|
|
|
+
|
|
|
+string toHtml(const fmpz_poly_t P){
|
|
|
+ fmpz_t temp;
|
|
|
+ fmpz_init(temp);
|
|
|
+ string str;
|
|
|
+ slong length=fmpz_poly_length(P);
|
|
|
+ if(length==0) return "0";
|
|
|
+ if(length==1){
|
|
|
+ fmpz* coeff=fmpz_poly_get_coeff_ptr(P,0);
|
|
|
+ return toHtml(coeff);
|
|
|
+ }
|
|
|
+ for(slong i=length-1;i>=0;--i){
|
|
|
+ fmpz* coeff=fmpz_poly_get_coeff_ptr(P,i);
|
|
|
+ if(not fmpz_is_zero(coeff)){
|
|
|
+ if(fmpz_is_one(coeff)){
|
|
|
+ if(i==0) str+=" + 1";
|
|
|
+ else if(i==1) str+="x";
|
|
|
+ else if(i==length-1) str+="x<sup>"+to_string(i)+"</sup>";
|
|
|
+ else str+=" + x<sup>"+to_string(i)+"</sup>";
|
|
|
+ }
|
|
|
+ else if(fmpz_is_pm1(coeff)){
|
|
|
+ if(i==0) str+=" - 1";
|
|
|
+ else if(i==1) str+=" - x";
|
|
|
+ else str+=" - x<sup>"+to_string(i)+"</sup>";
|
|
|
+ }
|
|
|
+ else if(fmpz_sgn(coeff)==-1){
|
|
|
+ fmpz_neg(temp,coeff);
|
|
|
+ str+=" - "+toHtml(temp);
|
|
|
+ if(i==1) str+=" x";
|
|
|
+ if(i>1) str+=" x<sup>"+to_string(i)+"</sup>";
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ if(i<length-1) str+=" + ";
|
|
|
+ str+=toHtml(coeff);
|
|
|
+ if(i==1) str+=" x ";
|
|
|
+ if(i>1) str+=" x<sup>"+to_string(i)+"</sup>";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return str;
|
|
|
+}
|
|
|
+
|
|
|
+string toHtml(const fmpz_poly_q_t R){
|
|
|
+ return toHtml(fmpz_poly_q_numref(R))+"/"+toHtml(fmpz_poly_q_denref(R));
|
|
|
+}
|
|
|
+
|
|
|
+string toHtml(const fmpz_poly_factor_t F){
|
|
|
+ string str;
|
|
|
+ if(not fmpz_is_one(&F->c)) str=toHtml(&F->c)+" · ";
|
|
|
+ for(ulong i=0;i<(F->num);++i){
|
|
|
+ if(i!=0) str+=" · ";
|
|
|
+ fmpz_poly_struct* P=&F->p[i];
|
|
|
+ if(fmpz_is_zero(fmpz_poly_get_coeff_ptr(P,0))) str+=toHtml(&F->p[i]);
|
|
|
+ else str+="("+toHtml(&F->p[i])+")";
|
|
|
+ slong e=F->exp[i];
|
|
|
+ if(e!=1) str+="<sup>"+to_string(e)+"</sup>";
|
|
|
+ }
|
|
|
+ return str;
|
|
|
+}
|
|
|
+
|
|
|
+int cmp(fmpz_poly_struct* P,fmpz_poly_struct* Q){
|
|
|
+ if(fmpz_poly_length(P)==fmpz_poly_length(Q)){
|
|
|
+ for(slong i=fmpz_poly_degree(P);i>=0;--i){
|
|
|
+ int c=fmpz_cmp(fmpz_poly_get_coeff_ptr(P,i),fmpz_poly_get_coeff_ptr(Q,i));
|
|
|
+ if(c!=0) return c;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if(fmpz_poly_length(P)<fmpz_poly_length(Q)) return -1;
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+int cmp(fmpz_poly_q_struct* R,fmpz_poly_q_struct* Q){
|
|
|
+ int c=cmp(fmpz_poly_q_denref(R),fmpz_poly_q_denref(Q));
|
|
|
+ if(c!=0) return c;
|
|
|
+ return cmp(fmpz_poly_q_numref(R),fmpz_poly_q_numref(Q));
|
|
|
+}
|
|
|
+
|
|
|
+int cmp(fmpz_poly_factor_struct* F1,fmpz_poly_factor_struct* F2){
|
|
|
+ if(F1->num==F2->num){
|
|
|
+ int c=fmpz_cmp(&F1->c,&F2->c);
|
|
|
+ if(c==0){
|
|
|
+ for(int i=0;i<F1->num;++i){
|
|
|
+ int d=cmp(&F1->p[i],&F2->p[i]);
|
|
|
+ if(d==0){
|
|
|
+ if(F1->exp[i]!=F2->exp[i]){
|
|
|
+ if(F1->exp[i]<F2->exp[i]) return -1;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return d;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+ if(F1->num<F2->num) return -1;
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+int cmp(fmpz_mat_struct* A,fmpz_mat_struct* B){
|
|
|
+ if(A->r==B->r){
|
|
|
+ if(A->c==B->c){
|
|
|
+ for(slong i=0;i<A->r;++i){
|
|
|
+ for(slong j=0;j<A->c;++j){
|
|
|
+ int c=fmpz_cmp(fmpz_mat_entry(A,i,j),fmpz_mat_entry(B,i,j));
|
|
|
+ if(c!=0) return c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if(A->c<B->c) return -1;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ if(A->r<B->r) return -1;
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+int cmp(fmpz_poly_mat_struct* A,fmpz_poly_mat_struct* B){
|
|
|
+ if(A->r==B->r){
|
|
|
+ if(A->c==B->c){
|
|
|
+ for(slong i=0;i<A->r;++i){
|
|
|
+ for(slong j=0;j<A->c;++j){
|
|
|
+ int c=cmp(fmpz_poly_mat_entry(A,i,j),fmpz_poly_mat_entry(B,i,j));
|
|
|
+ if(c!=0) return c;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ if(A->c<B->c) return -1;
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ if(A->r<B->r) return -1;
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void dispSage(ostream& os,const fmpz_mat_t A){
|
|
|
+ os<<"matrix(QQ,"<<A->r<<','<<A->c<<",[";
|
|
|
+ for(ulong i=0;i<A->r;++i){
|
|
|
+ for(ulong j=0;j<A->c;++j){
|
|
|
+ if(i!=0 or j!=0) os<<',';
|
|
|
+ os<<get(A,i,j);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ os<<"])";
|
|
|
+}
|
|
|
+
|
|
|
+ostream& operator<<(ostream& os,const fmpz_poly_mat_t A){
|
|
|
+ if(A->c==1){
|
|
|
+ os<<'['<<get(A,0,0)<<']';
|
|
|
+ for(ulong i=1;i<A->r;++i) os<<endl<<'['<<get(A,i,0)<<']';
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ os<<'['<<get(A,0,0);
|
|
|
+ for(ulong j=1;j<A->c;++j) os<<' '<<get(A,0,j);
|
|
|
+ os<<']';
|
|
|
+ for(ulong i=1;i<A->r;++i){
|
|
|
+ os<<endl<<'['<<get(A,i,0);
|
|
|
+ for(ulong j=1;j<A->c;++j) os<<' '<<get(A,i,j);
|
|
|
+ os<<']';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return os;
|
|
|
+}
|
|
|
+
|
|
|
+ void fmpz_poly_mat_init_set(fmpz_poly_mat_t A,fmpz_mat_t B){
|
|
|
+ fmpz_poly_mat_init(A,B->r,B->c);
|
|
|
+ for(slong i=0;i<B->r;++i){
|
|
|
+ for(slong j=0;j<B->c;++j){
|
|
|
+ fmpz_poly_set_coeff_fmpz(fmpz_poly_mat_entry(A,i,j),0,fmpz_mat_entry(B,i,j));
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|