/* SYMMETRICA V2.0 260298 */ /* file: part.c */ #include "def.h" #include "macro.h" #define callocobject callocobject_trace #undef callocobject static struct partition * callocpartition(); static int utiliser(); static int repartir(); static INT ordcon_char(); static INT m060588(); static INT m060588b(); static INT mem_counter_part=(INT)0; /* AK 100893 */ static struct partition **pa_sp = NULL; /* for internal managment of partition memory */ static INT pa_index = -1L; #define PASIZE (INT)1000 #ifdef VECTORTRUE #define M_KL_PA(a,b,c) (b_ks_pa(a,callocobject(),c) || m_l_v(b,S_PA_S(c))) #define B_KL_PA(a,b,c) (b_ks_pa(a,callocobject(),c) || b_l_v(b,S_PA_S(c))) #endif /* VECTORTRUE */ #define PART_CHECK_KIND(t,a,b)\ if (S_O_K(a) != PARTITION)\ WTO(t,a);\ if (S_PA_K(a) != b)\ wrong_kind_part(t,a,b); #ifdef PARTTRUE INT t_CHARPARTITION_PARTITION(); static char * part_kind_to_text(k) OBJECTKIND k; { switch(k) { case EXPONENT: return "exponent"; case VECTOR: return "vector"; case BITVECTOR: return "bitvector"; case FROBENIUS: return "frobenius"; default: return "unknown"; } } static INT wrong_kind_part(t,a,b) char *t; OP a; OBJECTKIND b; { char s[200]; sprintf(s,"%s: wrong kind of partition, should be %s but it was %s", t,part_kind_to_text(b),part_kind_to_text(S_PA_K(a))); error(s); return ERROR; } INT hookp(a) OP a; /* AK 110888 */ /* AK 280689 V1.0 */ /* AK 160890 V1.1 */ /* AK 180391 V1.2 */ /* AK 210891 V1.3 */ /* AK V2.0 160698 */ { INT erg = OK; PART_CHECK_KIND("hookp",a,VECTOR); if (S_PA_LI (a) <= 1L) return(TRUE); if (S_PA_II (a, S_PA_LI(a) - 2L) == 1L) return(TRUE); return(FALSE); ENDR("hookp"); } INT inc_partition(a) OP a; /* AK 2.0 090298 */ { INT erg = OK; CTO(PARTITION,"inc_partition",a); erg += inc_vector(S_PA_S(a)); ENDR("inc_partition"); } INT m_i_staircase(a,b) OP a,b; /* AK 2.0 090298 */ /* input: INTEGER object a output: PARTITION object 1,2,3,4,...,a */ { INT i; INT erg = OK; CTO(INTEGER,"m_i_staircase",a); if (S_I_I(a) <= (INT)0) { erg += error("m_i_staircase:input <= 0"); goto endr_ende; } CE2(a,b,m_i_staircase); erg += b_ks_pa(VECTOR,callocobject(),b); erg += m_l_v(a,S_PA_S(b)); for (i=0;i 1L) return FALSE; return TRUE; } else return error("strictp:wrong type of partiton"); ENDR("strictp"); } INT add_part_part(a,b,c) OP a,b,c; /* c = a + b */ /* AK 071189 */ /* AK 181289 V1.1 */ /* AK090891 V1.3 */ /* AK 2.0 090298 */ { INT i,j; INT erg = OK; PART_CHECK_KIND("add_part_part",a,VECTOR); PART_CHECK_KIND("add_part_part",b,VECTOR); CE3(a,b,c,add_part_part); if (S_PA_LI(a) <= S_PA_LI(b)) { erg += copy_partition(b,c); for (i=S_PA_LI(a)-1L,j=S_PA_LI(b)-1L;i>=(INT)0;i--,j--) M_I_I(S_PA_II(a,i) + S_PA_II(b,j),S_PA_I(c,j)); } else { erg += copy_partition(a,c); for (i=S_PA_LI(a)-1L,j=S_PA_LI(b)-1L;j>=(INT)0;i--,j--) M_I_I(S_PA_II(a,i) + S_PA_II(b,j),S_PA_I(c,i)); } ENDR("add_part_part"); } INT remove_part_part(a,b,c) OP a,b,c; /* AK 070995 */ /* 23344 , 24 ->> 334 */ /* AK 2.0 090298 */ { INT erg = OK; INT i,j,k; OP d; CTO(PARTITION,"remove_part_part",a); CTO(PARTITION,"remove_part_part",b); CE3(a,b,c,remove_part_part); if (S_PA_K(a) != S_PA_K(b)) { erg += error("remove_part_part entered different kind of partitions"); } else if (S_PA_K(a) == VECTOR) { d = callocobject(); erg += m_il_nv(S_PA_LI(a),d); for (i=0,j=0,k=0;i 1222334 */ /* AK 2.0 090298 */ { OP d; INT erg = OK; CE3(a,b,c,append_part_part); CTO(PARTITION,"append_part_part",a); if (S_O_K(b) == VECTOR) { erg += copy(b,c); erg += inc(c); erg += copy_partition(a,S_V_I(c,S_V_LI(c)-1)); goto endr_ende; } else if (S_O_K(b) == EMPTY) { erg += copy_partition(a,c); goto endr_ende; } CTO(PARTITION,"append_part_part",b); if (S_PA_K(a) != S_PA_K(b)) { erg += error("append_part_part: different kind of partitions"); } else if (S_PA_K(a) == VECTOR) { d = callocobject(); erg += append(S_PA_S(a),S_PA_S(b),d); erg += m_v_pa(d,c); erg += freeall(d); } else if (S_PA_K(a) == EXPONENT) { erg += b_ks_pa(EXPONENT,callocobject(),c); erg += add_integervector(S_PA_S(a), S_PA_S(b), S_PA_S(c)); } else { erg += error("append_part_part works only for VECTOR,EXPONENT partitions"); } ENDR("append_part_part"); } INT add_partition(a,b,c) OP a,b,c; /* AK 060789 V1.0 */ /* AK 280590 V1.1 */ /* AK 200891 V1.3 */ /* AK 2.0 090298 */ { INT erg = OK; /* AK 040292 */ CE3(a,b,c,add_partition); switch(S_O_K(b)) { case PARTITION : erg += add_part_part(a,b,c); break; #ifdef SCHURTRUE case SCHUR : erg += m_pa_s(a,c); erg+=add(c,b,c); break; #endif /* SCHURTRUE */ default : { printobjectkind(b); return error("add_partition:wrong second type"); }; } ENDR("add_partition"); } INT first_composition(w,parts,c) OP parts, w, c; /* AK 090487 */ /* AK 201189 V1.1 */ /* AK 150591 V1.2 */ /* AK 200891 V1.3 */ /* AK 2.0 090298 */ { INT i,erg=OK,wp,ww; CTO(INTEGER,"first_composition",w);ww=S_I_I(w); CTO(INTEGER,"first_composition",parts);wp=S_I_I(parts); if (wp <= 0) { erg += error("first_composition:number of parts <= 0"); goto endr_ende; } if (ww <= 0) { erg += error("first_composition:weight <= 0"); goto endr_ende; } erg += m_il_v(wp,c); erg += M_I_I(ww,S_V_I(c,(INT)0)); for (i=1L;i S_I_I(n)) { erg += error("first_subset:input variable k > n"); goto endr_ende; } erg += m_l_nv(n,c); for (i=0;i=0;i--) { if (S_V_II(c,i) == 0) break; else m++; } /* m ist die anzahl der gelesenen 1en bis zur 0 */ for (; i>=0 ;i--) { if (S_V_II(c,i) == 1) break; } if (i == -1) return LAST_SUBSET; M_I_I(0, S_V_I(d,i)); M_I_I(1,S_V_I(d,i+1)); for (i=i+2; m>0 ; i++,m--) M_I_I(1,S_V_I(d,i)); for (; i=0;i--) { if (S_V_II(c,i) == 0) break; else m++; } /* m ist die anzahl der gelesenen 1en bis zur 0 */ for (; i>=0 ;i--) { if (S_V_II(c,i) == 1) break; } if (i == -1) return LAST_SUBSET; M_I_I(0, S_V_I(c,i)); M_I_I(1,S_V_I(c,i+1)); for (i=i+2; m>0 ; i++,m--) M_I_I(1,S_V_I(c,i)); for (; i=(INT)0; i--,j--) if (S_V_II(newcomp,i) == (INT)0) { rest += S_V_II(newcomp,j); C_I_I(S_V_I(newcomp,j),(INT)0); } else if (S_V_II(newcomp,i) > (INT)0) { DEC_INTEGER(S_V_I(newcomp,i)); C_I_I(S_V_I(newcomp,j),S_V_II(newcomp,j)+1L+rest); return(OK); }; return(LASTCOMP); } INT conjugate_partition(part,b) OP part, b; /* AK 220587 */ /* AK 060789 V1.0 */ /* AK 240490 V1.1 */ /* AK 200891 V1.3 */ /* AK 200298 V2.0 */ { INT i,j,k=(INT)0,m; /* k ist die adresse an der geschrieben wird im b */ INT erg = OK; CTO(PARTITION,"conjugate_partition",part); CE2(part,b,conjugate_partition); if (S_PA_K(part) == EXPONENT) /* AK 170692 */ { OP c = callocobject(); erg += t_EXPONENT_VECTOR(part,c); erg += conjugate_partition(c,b); erg += freeall(c); erg += t_VECTOR_EXPONENT(b,b); goto endr_ende; } else if (S_PA_K(part) == FROBENIUS) { erg += b_ks_pa(FROBENIUS,callocobject(),b); erg += m_il_v((INT)2,S_PA_S(b)); erg += copy_integervector(S_V_I(S_PA_S(part),0), S_V_I(S_PA_S(b),1) ); erg += copy_integervector(S_V_I(S_PA_S(part),1), S_V_I(S_PA_S(b),0) ); goto endr_ende; } else if (S_PA_K(part) != VECTOR) { erg += error("conjugate_partition: works only for VECTOR,EXPONENT,FROBENIUS type"); goto endr_ende; } if (S_PA_LI(part) == (INT)0) { erg += copy_partition(part,b); goto endr_ende; } erg += b_ks_pa(VECTOR,callocobject(),b); erg += m_il_v(S_PA_II(part,S_PA_LI(part)-1L),S_PA_S(b)); j = S_PA_LI(part) - 1L; /* dies sind die adressen in den beiden partitionen */ m = S_PA_LI(b)+S_PA_LI(part)+1L; /* dies ist die laenge der permutation + 1 */ for( i=m-1L; i > (INT)0 ; i--) { if (j>=0) if (i == S_PA_II(part,j)+j+1L ) j-- ; else { M_I_I(m-i- k - 1L,S_PA_I(b,k)); k++ ; } else { M_I_I(m-i- k - 1L,S_PA_I(b,k)); k++ ; } } ENDR("conjugate_partition"); } INT ferrers_partition(part) OP part; /* AK 060789 V1.0 */ /* AK 150690 V1.1 */ /* AK 200891 V1.3 */ /* AK 240298 V2.0 */ { INT i,j; INT erg = OK; OP z; CTO(PARTITION,"ferrers_partition",part); if (S_PA_K(part) == EXPONENT) { z = callocobject(); erg += t_EXPONENT_VECTOR(part,z); erg += ferrers_partition(z); erg += freeall(z); goto endr_ende; } PART_CHECK_KIND("ferrers_partition",part,VECTOR); printf("\n"); for (i=(INT)0; irow_length)) { fprintf(f,"\n"); zeilenposition = (INT)0; } ENDR("fprint_partition"); } INT sprint_partition(f,partobj) char *f; OP partobj; /* AK V2.0 200298 */ { INT i; INT erg = OK; CTO(PARTITION,"sprint_partition",partobj); if (S_PA_K(partobj) == FROBENIUS) /* AK 101292 */ { erg += sprint(f,S_PA_S(partobj)); goto endr_ende; } else if (S_PA_K(partobj) == BITVECTOR) { erg+= sprint(f,S_PA_S(partobj)); goto endr_ende; } f[0]='\0'; /* AK 151298 to handle zero partition */ for( i = (INT)0; i S_I_I(n)/2L) { erg += m_i_i((INT)0,res); } else { i = callocobject(); j = callocobject(); zw = callocobject(); /* initialisieren i = n-m, j = m, res = 0 */ M_I_I(S_I_I(n)-S_I_I(m),i); COPY_INTEGER(m,j); erg += m_i_i((INT)0,res); while(S_I_I(j) <= S_I_I(i) ) { erg += gupta_nm(i,j,zw); if (S_O_K(zw) != INTEGER) add_apply(zw,res); else if (not NULLP_INTEGER(zw)) add_apply(zw,res); /* nicht aufrufen falls 0 */ INC_INTEGER(j); } erg += freeall(zw); erg += freeall(i); erg += freeall(j); } ENDR("gupta_nm"); } #ifdef MATRIXTRUE INT gupta_tafel(mx,mat) OP mx,mat; /* AK 220888 */ /* AK 060789 V1.0 */ /* AK 120390 V1.1 */ /* AK 200891 V1.3 */ /* AK 200298 V2.0 */ /* mx and mat may be equal */ { INT i,j,k; OP h,l,zw; INT erg = OK; h = callocobject(); l = callocobject(); M_I_I(S_I_I(mx),h); M_I_I((S_I_I(mx) / 2L)+1L,l); erg += b_lh_nm(l,h,mat); for (i=(INT)0; i< S_I_I(mx); i++) { for (j=(INT)0;j<=i/2L;j++) { for (k=(INT)0; j+k < (i-j)/2L ; k++) /* die rekursion */ { erg += add_apply(S_M_IJ(mat,i-j-1L,j+k),S_M_IJ(mat,i,j)); } erg += inc(S_M_IJ(mat,i,j)); }; } ENDR("gupta_tafel"); } INT gupta_nm_speicher(n,m,res) OP n,m,res; /* AK 120390 V1.1 */ /* AK 200891 V1.3 */ /* AK 200298 V2.0 */ /* n,m,res may be equal */ { OP mat; INT erg = OK; CTO(INTEGER,"gupta_nm_speicher",n); CTO(INTEGER,"gupta_nm_speicher",m); if (S_I_I(n) <= 0) { erg += error("gupta_nm_speicher;input <= 0"); goto endr_ende; } if (S_I_I(n) == S_I_I(m)) { M_I_I(1,res); goto endr_ende; } if (S_I_I(m) > S_I_I(n)/2L) { M_I_I(0,res); goto endr_ende; } mat = callocobject(); erg += gupta_tafel(n,mat); erg += copy(S_M_IJ(mat,S_I_I(n)-1L,S_I_I(m)-1L),res); erg += freeall(mat); ENDR("gupta_nm_speicher"); } #endif /* MATRIXTRUE */ #endif /* PARTTRUE */ #ifdef PARTTRUE INT hook_length_augpart(p,i,j,res) OP p,res; INT i,j; /* AK 060988 hakenlaenge */ /* AK 060789 V1.0 */ /* AK 080290 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ /* p and res may be equal */ { INT e,k; INT erg = OK; if (not EMPTYP(res)) if (S_O_K(res) != INTEGER) freeself(res); if (i >= S_PA_LI(p)) { M_I_I(0,res); } else if (j >= S_PA_II(p,i)-i) { M_I_I(0,res); } else { e = S_PA_II(p,i) - j - i; /* nun noch die zeilen dazu */ for (k=i-1L; k>= (INT)0; k--) if (S_PA_II(p,k) -1L -k >= j) e++; else break; M_I_I(e,res); } ENDR("hook_length_augpart"); } INT hook_diagramm(p,m) OP p,m; /* AK 010295 */ /* AK V2.0 100298 */ /* input: PARTITION object output: MATRIX object with hooklength */ { INT erg = OK, i,j; PART_CHECK_KIND("hook_diagramm",p, VECTOR); CE2(p,m,hook_diagramm); erg += m_ilih_m(S_PA_II(p,S_PA_LI(p)-1), S_PA_LI(p), m); for (i=0L;i= S_PA_LI(p)) return(M_I_I(0,b), OK); if (j >= S_PA_II(p,S_PA_LI(p)-1L-i)) return(M_I_I(0,b), OK); e = S_PA_II(p,S_PA_LI(p)-1L-i) - j; /* nun noch die zeilen dazu */ for (k=i+1L; k= j) e++; else break; M_I_I(e,b); ENDR("hook_length"); } INT dimension_partition(a,b) OP a,b; /* AK 150988 */ /* AK 060789 V1.0 */ /* AK 080290 V1.1 */ /* AK 050391 V1.2 */ /* AK 200891 V1.3 */ /* AK 200298 V2.0 */ /* input: PARTITION object ouput: dimension of corresponding irreducible Sn character INTEGER object or LONGINT object */ /* a and b may be equal */ { OP zaehler, nenner, zw; INT i,j; INT erg = OK; CTO(PARTITION,"dimension_partition",a); if (S_PA_K(a) == EXPONENT) /* AK 170692 */ { zw = callocobject(); erg += t_EXPONENT_VECTOR(a,zw); erg += dimension_partition(zw,b); erg += freeall(zw); } else if (S_PA_K(a) != VECTOR) { error("dimension_partition: wrong kind of partition"); erg = ERROR; } else { zw = callocobject(); zaehler = callocobject(); erg = weight(a,zw); erg += fakul(zw,zaehler); erg += freeself(zw); nenner = callocobject(); erg += M_I_I(1L,nenner); for (i=(INT)0;i (INT)0) M_I_I(S_PA_LI(part), S_PA_I(part,(INT)0)); ENDR("last_part_EXPONENT"); } INT first_part_VECTOR(n,part) OP n,part; /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { return first_partition(n,part); } INT last_part_VECTOR(n,part) OP n,part; /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { return last_partition(n,part); } INT first_part_EXPONENT(n,part) OP n,part; /* AK 170298 V2.0 */ /* input: n = INTEGER object >= 0 output: PARTITION-EXPONENT object 00000...00001 of given weight n */ /* n and part may be equal */ { INT i; INT erg = OK; CTO(INTEGER,"first_part_EXPONENT",n); i = S_I_I(n); if (i < (INT)0) { fprintf(stderr,"input = %ld\n",i); erg += error("first_part_EXPONENT:input < 0"); goto endr_ende; } erg += b_ks_pa(EXPONENT,callocobject(),part); erg += m_il_nv(i,S_PA_S(part)); if (i > 0) M_I_I(1L, S_PA_I(part,S_PA_LI(part)-1L)); ENDR("first_part_EXPONENT"); } INT last_partition(n,part) OP n,part; /* AK 190587 */ /* die prozedur erzeugt aus der Zahl n die Partition [1^n], die letzte Partition bezueglich nextpartition bzgl. Dominanzordnung und auch lexikographisch */ /* n wird nicht verwendet */ /* AK 060789 V1.0 */ /* AK 300590 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { INT i; INT erg = OK; /* AK 020692 */ CTO(INTEGER,"last_partition",n); CE2(n,part,last_partition); if (S_I_I(n) < (INT)0) /* AK 020692 */ { fprintf(stderr,"input = %ld\n",S_I_I(n)); erg += error("last_partition:input < 0"); goto endr_ende; } erg += b_ks_pa(VECTOR,callocobject(),part); erg += m_l_v(n,S_PA_S(part)); for (i=(INT)0;i 1) /* bsp: 2345 --> 11345 */ { length = callocobject(); M_I_I(S_PA_LI(part)+1L, length); B_KL_PA(VECTOR,length,next); M_I_I(1L,S_PA_I(next,(INT)0)); M_I_I(S_PA_II(part,(INT)0)-1L,S_PA_I(next,1L)); for (i=2L;i 1L) break; if (i == S_PA_LI(part)) return(LASTPARTITION); k = S_PA_LI(part) -i; /* restlaenge */ m = S_PA_II(part,i); n = m - 1L ; /* neuer wert in next */ j = (i + m) / n; o =(i + m) % n ; if (o == (INT)0) j--; length = callocobject(); M_I_I( j+k, length); B_KL_PA(VECTOR,length,next); if (o != (INT)0) { M_I_I(o ,S_PA_I(next,(INT)0)); o=1L; }; for (m=o;m<=j;m++) M_I_I(n, S_PA_I(next,m)); for (;m(INT)0) { index=i++; break; }; } memcpy( (char *)S_PA_I(next,i), (char *)S_PA_I(part,i), (int) (l-i+1L)*sizeof(struct object) ); summe = S_PA_II(part,(INT)0); /* an der stelle index wird der index um eins decrementiert */ summe = summe + index + 1L; M_I_I(S_PA_II(part,index)-1L, S_PA_I(next,index)); /* nun nach rechts wieder aufbauen */ for (i=index-1L;i>=(INT)0;i--) { value = summe / (i+1L); M_I_I(value,S_PA_I(next,i)); summe = summe % (i+1L); if (summe == (INT)0) break; i = summe; } return(OK); } INT next_part_EXPONENT_apply(part) OP part; /* AK V2.0 211100 */ { INT l = S_PA_LI(part); INT i,index=(INT)0,k; INT summe; INT value; if (l == (INT)0) return(LASTPARTITION); if (S_PA_II(part,(INT)0) == l) return(LASTPARTITION); /* part = n 0 0 0 0 0 0 ... */ // b_ks_pa(EXPONENT,callocobject(),next); // m_il_v(l--,S_PA_S(next)); // M_I_I(0,S_PA_I(next,(INT)0)); for (i=1L;i<=l;i++) { k = S_PA_II(part,i); // M_I_I(k,S_PA_I(next,i)); if (k>(INT)0) { index=i++; break; }; } /* memcpy( (char *)S_PA_I(next,i), (char *)S_PA_I(part,i), (int) (l-i+1L)*sizeof(struct object) ); */ summe = S_PA_II(part,(INT)0); M_I_I(0,S_PA_I(part,(INT)0)); /* an der stelle index wird der index um eins decrementiert */ summe = summe + index + 1L; M_I_I(S_PA_II(part,index)-1L, S_PA_I(part,index)); /* nun nach rechts wieder aufbauen */ for (i=index-1L;i>=(INT)0;i--) { value = summe / (i+1L); M_I_I(value,S_PA_I(part,i)); summe = summe % (i+1L); if (summe == (INT)0) break; i = summe; } return(OK); } INT numberofpart_i(n) OP n; /* AK 060789 V1.0 */ /* AK 120390 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { OP zw; INT i; INT erg = OK; CTO(INTEGER,"numberofpart_i",n); zw=callocobject(); numberofpart(n,zw); i=S_I_I(zw); freeall(zw); return(i); ENDR("numberofpart_i"); } INT numberofpart(n,x) OP n,x; /* AK 190587 */ /* AK 060789 V1.0 */ /* AK 120390 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ /* input: INTEGER object n output: INTEGER or LONGINT object = number of parts of weight n */ /* n and x may be equal */ { OP c,d; INT erg = OK; /* AK 041291 */ CTO(INTEGER,"numberofpart",n); if (S_I_I(n) < (INT) 0) { erg += error("numberofpart: input <= 0"); goto endr_ende; } else if (S_I_I(n) < (INT) 2) { m_i_i((int) 1, x); goto endr_ende; } c = callocobject(); if (S_I_I(n) < (INT)30) { erg += last_partition(n,c); erg += M_I_I(indexofpart(c)+(INT)1,x); } else { M_I_I(S_I_I(n)+1L,c); erg += gupta_nm_speicher(c,cons_eins,x); } erg += freeall(c); ENDR("numberofpart"); } INT indexofpart(part) OP part; /* AK 190587 */ /* AK 060789 V1.0 */ /* AK 260690 V1.1 */ /* AK 200891 V1.3 */ /* AK 200298 V2.0 */ { OP b,a; INT i=(INT)-1,erg=OK,comperg; CTO(PARTITION,"indexofpart",part); a = callocobject(); if (S_PA_K(part) != VECTOR) { if (S_PA_K(part) != EXPONENT) { erg += error("indexofpart:wrong kind of part"); goto endr_ende; } erg += t_EXPONENT_VECTOR(part,a); i = indexofpart(a); erg += freeall(a); if (erg != OK) goto endr_ende; return i; } erg += weight_partition(part,a); b = callocobject(); erg += first_partition(a,b); i=(INT)0; while ((comperg = comp_partition(b,part)) != (INT)0) { i++; if (not next(b,b)) { debugprint(b); erg += error("indexofpart:ERROR"); } }; erg += freeall(b); erg += freeall(a); if (erg != OK) goto endr_ende; return(i); ENDR("indexofpart"); } INT ordcen(part,res) OP part, res; /* AK 010888 ordnung der konjugiertenklasse ist der index des zentralisators */ /* AK 060789 V1.0 */ /* AK 071289 V1.1 */ /* AK 150591 V1.2 */ /* AK 200891 V1.3 */ /* AK 200298 V2.0 */ { OP h1,h2,zw; INT erg = OK; CTO(PARTITION,"ordcen",part); zw = callocobject(); h1 = callocobject(); h2 = callocobject(); erg += ordcon(part,h2); erg += weight_partition(part,zw); erg += fakul(zw,h1); erg += ganzdiv(h1,h2,res); /* ist ganzzahlig */ erg += freeall(zw); erg += freeall(h2); erg += freeall(h1); ENDR("ordcen"); } #ifdef TABLEAUXTRUE INT m_tableaux_polynom(a,c) OP a, c; /* AK 250789 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { /* a ist poly of tableaux c wird poly of monom */ /* AK 060588 */ OP zeiger; INT erg = OK; zeiger = a; erg += init(POLYNOM,c); while( zeiger != NULL) { OP b = callocobject(); erg += b_skn_po(callocobject(),callocobject(),NULL,b); M_I_I(1L,S_PO_K(b)); erg += content_tableaux(S_PO_S(zeiger),S_PO_S(b)); insert(b,c,add_koeff,comp_monomvector_monomvector); zeiger = S_PO_N(zeiger); }; ENDR("m_tableaux_polynom"); } INT m_part_tableaux(part,alph,res) OP part,alph,res; /* AK 070588 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { return(m_umriss_tableaux(part,alph,res)); } INT m_umriss_tableaux(umriss,alph,res) OP umriss,alph,res; /* AK 070588 */ /* erzeugt aus umriss eine liste der tableaus von diesen umriss mit eintraegen 1,2,..,alph */ /* ergebnis ist polynom */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ /* input: PARTITION object umriss INTEGER object alph output: */ { OP a,b,c; OP start; INT i,j; INT erg = OK; CTO(INTEGER,"m_umriss_tableaux",alph); PART_CHECK_KIND("m_umriss_tableaux",umriss,VECTOR); CE3(umriss,alph,res,m_umriss_tableaux); erg += init(LIST,res); if (S_I_I(alph) < S_PA_LI(umriss)) return(OK); a = callocobject(); b = callocobject(); erg += copy(umriss,a); erg += m_u_t(a,b); /* damit haben wird das tablaux */ j = zeilenanfang(b,0L); start = S_T_IJ(b,0L,j); /* start ist die linke untere ecke */ for (i= (INT)0; i< S_I_I(alph); i++) { M_I_I(i+1L,start); /* initialisieren */ erg += m060588(b,alph,res); } erg += freeall(a); erg += freeall(b); ENDR("m_umriss_tableaux"); } static INT m060588(tab,alph,res) OP tab,alph,res; /* alph ist maximaler eintrag */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { OP b,c; INT i,j; INT grenze; INT lasti,lastj; for (i=S_T_HI(tab)-1;i>= 0;i--) { j=zeilenanfang(tab,i); /* erster erlaubter index */ if (not EMPTYP(S_T_IJ(tab,i,j))) break; }; lasti = i; /* lasti ist zeile in der letzter eintrag */ grenze = zeilenende(tab,lasti); for ( j=zeilenanfang(tab,lasti); /* erster erlaubter index */ j<= grenze; j++) if (EMPTYP(S_T_IJ(tab,lasti,j))) break; lastj = j; /* lastj ist letzter eintrag + 1 */ if (lastj <= grenze) { /* d.h. in der zeile kann noch eingetragen werden */ INT m; m = S_T_IJI(tab,lasti,lastj-1); /* m = der letzte eintrag */ if (lasti == /* s_t_hi(tab)-1*/ 0L) /* letzte zeile */ M_I_I(m,S_T_IJ(tab,lasti,lastj)); /* rechts anfuegen der gleichen zahl */ else if (emptyp(S_T_IJ(tab,lasti-1L,lastj))) /* bei schief unterhalb leer */ M_I_I(m,S_T_IJ(tab,lasti,lastj)); /* rechts anfuegen der gleichen zahl */ else { /* schauen ob unterhalb groesserer eintrag */ m = (S_T_IJI(tab,lasti-1L,lastj) >= m ? S_T_IJI(tab,lasti-1L,lastj)+1 : m); if (m > S_I_I(alph)) goto m060588nein; /* kann nicht einsetzen */ M_I_I(m,S_T_IJ(tab,lasti,lastj)); }; return(m060588(tab,alph,res)); }; /* falls in der zeile nicht mehr eingetragen werden kann */ i = i+1L; /* neue zeilenzahl */ if (i < S_T_HI(tab)) { j = zeilenanfang(tab,i); /* neue spaltenzahl */ if (not emptyp(s_t_ij(tab,i-1L,j))) /* unterhalb der neuen position ist ein eintrag */ { if (S_T_IJI(tab,i-1L,j)+1 > S_I_I(alph)) goto m060588nein; M_I_I(s_t_iji(tab,i-1L,j)+1L,s_t_ij(tab,i,j)); return(m060588(tab,alph,res)); } else M_I_I(1L,s_t_ij(tab,i,j)); }; /* nun sind wir am ende */ b = callocobject(); c = callocobject(); copy(tab,b); b_s_po(b,c); insert(c,res,NULL,NULL); /* jetzt muss versucht werden das naechste tableaux zu bekommen */ m060588nein: if (m060588b(tab,alph) == TRUE) m060588(tab,alph,res); /* d.h noch nicht letztes tableaux */ return(OK); } static INT m060588b(tab,alph) OP tab,alph; /* es wird versucht das naechste tableaux zu bekommen */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { INT i,j; INT lastj = zeilenanfang(tab,0L); for (i=S_T_HI(tab)-1; i>=0 ;i--) for (j= S_T_LI(tab)-1L;j >= (INT)0; j--) if (not EMPTYP(s_t_ij(tab,i,j))) /* es gibt einen eintrag */ if (i == 0L && j == lastj) return(FALSE); /* wir sind am ende */ else if (s_t_iji(tab,i,j) < S_I_I(alph)) { inc(s_t_ij(tab,i,j)); return(TRUE); } else { freeself(s_t_ij(tab,i,j)); return(m060588b(tab,alph)); } return(FALSE); } #endif /* TABLEAUXTRUE */ INT t_augpart_part(a,b) OP a,b; /* AK 150988 */ /* AK 060789 V1.0 */ /* AK 170190 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { INT i,s; copy(a,b); C_O_K(b,PARTITION); for (i=(INT)0;i S_PA_LI(b)) { erg = (INT)memcmp(ac,bc, (sizeof(struct object) * S_PA_LI(b) )); if (erg == (INT)0) erg = (INT)1; goto cpende; } } else if (S_PA_K(a) == EXPONENT) { if (S_PA_LI(a) == S_PA_LI(b)) /* AK 011097 */ { erg = (INT)memcmp( (char *) S_V_S(S_PA_S(a)), (char *) S_V_S(S_PA_S(b)), ( sizeof(struct object) * S_PA_LI(a) )); goto cpende; } for ( i=(INT)0; i= S_PA_LI(b) ) { if (S_PA_II(a,i) != (INT)0) { erg = (INT)1; goto cpende; } } else if (S_PA_II(a,i) > S_PA_II(b,i)) { erg = (INT)1; goto cpende; } else if (S_PA_II(a,i) < S_PA_II(b,i)) { erg = (INT)-1; goto cpende; } } for ( ; i=(INT)0;i--) { SYM_free(pa_sp[i]); mem_counter_part--; /* AK 100893 */ } if (pa_sp != NULL) { erg += SYM_free(pa_sp); pa_sp = NULL; /* AK 160893 */ pa_index = -1L; } if (mem_counter_part != (INT)0) /* AK 100893 */ { fprintf(stderr,"mem_counter_part = %ld\n",mem_counter_part); erg += error("memory problem with partitions"); } return erg; } INT freeself_partition(a) OP a; /* AK 110488 */ /* AK 060789 V1.0 */ /* AK 211189 V1.1 */ /* AK 120691 V1.2 */ /* AK 070891 V1.3 */ /* AK V2.0 200298 */ { OBJECTSELF d; INT erg = OK; if (pa_sp == NULL) /* AK 111091 */ { pa_sp = (struct partition **)SYM_malloc( PASIZE * sizeof(struct partition *)); } if (S_O_K(a) == CHARPARTITION) SYM_free(S_PA_S(a)); else if (S_PA_K(a) == FROBENIUS) erg += freeall(S_PA_S(a)); else { if (S_PA_S(a) != NULL) erg += freeall(S_PA_S(a)); } d = S_O_S(a); if (pa_index+1 < PASIZE) /* AK 111091 */ pa_sp[++pa_index]=d.ob_partition; else { SYM_free(d.ob_partition); mem_counter_part--; /* AK 100893 */ } C_O_K(a,EMPTY); ENDR("freeself_partition"); } INT copy_partition(a,b) OP a,b; /* AK 060789 V1.0 */ /* AK 191289 V1.1 */ /* AK 070891 V1.3 */ /* AK V2.0 200298 */ { INT erg = OK; erg += b_ks_pa(S_PA_K(a),callocobject(),b); erg += m_il_v(S_PA_LI(a),S_PA_S(b)); memcpy( (char *) S_V_S(S_PA_S(b)), (char *) S_V_S(S_PA_S(a)), (int)(S_PA_LI(a)*sizeof(struct object)) ); C_O_K(b,S_O_K(a)); /* copy of AUG_PART e.g. */ ENDR("copy_partition"); } INT tex_partition(part) OP part; /* AK 101187 */ /* output of a PARTITIONobject in format for TeX */ /* AK 060789 V1.0 */ /* AK 170190 V1.1 */ /* AK 070291 V1.2 texout for output */ /* AK 070891 V1.3 */ /* AK V2.0 200298 */ { INT erg = OK; if (texmath_yn == 0L) /* if not in math mode */ fprintf(texout,"\\ $ "); erg += fprint(texout,part); texposition = (INT)0; if (texmath_yn == 0L) /* if not in math mode */ fprintf(texout," $\\ "); ENDR("tex_partition"); } static struct partition * callocpartition() /* AK 060789 V1.0 */ /* AK 170889 malloc statt calloc */ /* AK 170190 V1.1 */ /* AK 070891 V1.3 */ /* AK V2.0 200298 */ { struct partition *erg; if (pa_index > -1L) erg = pa_sp[pa_index--]; else { erg = (struct partition *) SYM_malloc(sizeof(struct partition)); mem_counter_part++; /* AK 100893 */ } if (erg == NULL) error("callocpartition: no memory"); return(erg); } INT inversordcen(part,ergeb) OP part, ergeb; /* AK 210387 */ /* AK 060789 V1.0 */ /* AK 170190 V1.1 */ /* AK 070891 V1.3 */ /* AK V2.0 200298 */ /* input: PARTITION object output: BRUCH object giving invers order of centraliser of S_n labeled by the partition */ { INT i; INT erg = OK; /* AK 090692 */ OP sp; PART_CHECK_KIND("inversordcen",part,VECTOR); CE2(part,ergeb,inversordcen); sp = callocobject(); m_i_i(1L,ergeb); M_I_I(1L,sp); for (i=(INT)0; i(INT)0) { if (S_PA_II(part,i) == S_PA_II(part,(i-1L))) { INC_INTEGER(sp); erg += mult_apply(sp,ergeb); } else M_I_I(1L,sp); }; erg += mult_apply(S_PA_I(part,i),ergeb); }; erg += invers_apply(ergeb); erg += freeall(sp); ENDR("inversordcen"); } INT ordcon(part,res) OP part, res; /* AK 200387 */ /* AK 060789 */ /* AK 060789 V1.0 */ /* AK 081289 V1.1 */ /* AK 070891 V1.3 */ /* AK V2.0 200298 */ /* input: PARTITION object output: INTEGER or LONGINT object giving the size of the conjugacy class in S_n labled by the partition */ { INT i; INT erg = OK; OP ergebnis,sp; OP h1; if (S_O_K(part) == CHARPARTITION) /* AK 170593 */ return ordcon_char(part,res); PART_CHECK_KIND("ordcon",part,VECTOR); CE2(part,res,ordcon); h1 = callocobject(); sp=callocobject(); M_I_I(1L,sp); ergebnis=callocobject(); M_I_I(1L,ergebnis); if (not EMPTYP(res)) if (S_O_K(res) != INTEGER) erg += freeself(res); for (i=(INT)0; i(INT)0) { if (S_PA_II(part,i) == S_PA_II(part,(i-1L))) { INC_INTEGER(sp); erg += mult_apply_integer(sp,ergebnis); } else M_I_I(1L,sp); }; erg += mult_apply_integer(S_PA_I(part,i),ergebnis); }; erg += weight_partition(part,h1); erg += fakul(h1,sp); erg += freeall(h1); erg += ganzdiv(sp,ergebnis,res); /* diese division ist ganzzahlig */ erg += freeall(sp); erg += freeall(ergebnis); ENDR("ordcon"); } static INT ordcon_char(part,res) OP part, res; /* AK V2.0 200298 */ { INT i; INT erg = OK; OP ergebnis,sp; OP h1,h2; if (S_O_K(part) != CHARPARTITION) /* AK 170593 */ return ERROR; if (S_PA_K(part) != VECTOR) return ERROR; h1 = callocobject(); h2 = callocobject(); sp=callocobject(); M_I_I(1L,sp); ergebnis=callocobject(); M_I_I(1L,ergebnis); if (not EMPTYP(res)) if (S_O_K(res) != INTEGER) erg += freeself(res); for (i=(INT)0; i(INT)0) { if (S_PA_CII(part,i) == S_PA_CII(part,(i-1L))) { INC_INTEGER(sp); erg += mult_apply_integer(sp,ergebnis); } else M_I_I(1L,sp); }; M_I_I(S_PA_CII(part,i),h2); /* AK 170593 */ erg += mult_apply_integer(h2,ergebnis); }; erg += weight_partition(part,h1); erg += fakul(h1,sp); erg += freeall(h1); erg += ganzdiv(sp,ergebnis,res); /* diese division ist ganzzahlig */ erg += freeall(sp); erg += freeall(ergebnis); erg += freeall(h2); ENDR("ordcon_char"); } static INT mycc(a,b) OP a,b; { return S_I_I(a)-S_I_I(b); } INT m_v_pa(vec,part) OP vec, part; /* AK 060789 V1.0 */ /* AK 240490 V1.1 */ /* AK 150591 V1.2 */ /* AK 070891 V1.3 */ /* AK V2.0 200298 */ /* input: VECTOR object with INTEGER entries >= 0 output: PARTITION object got by ordering the entries and removinf the zeros */ { INT i=(INT)0,j, erg=OK; OP self; OP zz; CE2(vec,part,m_v_pa); CTTO(VECTOR,INTEGERVECTOR,"m_v_pa",vec); self = callocobject(); erg += copy_integervector(vec,self); qsort(S_V_S(self), S_V_LI(self), sizeof(struct object), mycc); if (S_V_II(self,(INT)0) < (INT)0) { INT err; erg += freeall(self); err=error("m_v_pa: negativ entries"); if (err == ERROR_EXPLAIN) { fprintf(stderr,"the wrong input vector was "); fprintln(stderr,vec); } } while (S_V_II(self,i) == (INT)0) /* eintraege = 0 werden ueberlesen */ if (i++ == (S_V_LI(self) - 1L)) { erg += freeall(self); erg += first_partition(cons_null,part); goto mvpa_ende; /* nur nullen */ } /* die laenge der ergebnis-partition vectorlaenge - anzahl der nullen */ if ((S_V_LI(self)-i) == 1L) /* AK 121093 */ { j = S_V_II(self,i); erg += m_il_v(1L,self); M_I_I(j,S_V_I(self,(INT)0)); } else { M_I_I(S_V_LI(vec) - i,S_V_L(self)); for (j=0;j= 0 */ { INT erg = OK; OP c; CTO(INTEGER,"m_i_pa",i); if (S_I_I(i) < 0) { erg += error("INTEGER < 0 in m_i_pa"); goto endr_ende; } c = callocobject(); M_I_I(S_I_I(i),c); erg += b_i_pa(c,result); ENDR("m_i_pa"); } INT b_i_pa(integer,res) OP integer,res; /* AK 140687 */ /* Bsp: 5 --> [5] */ /* AK 060789 V1.0 */ /* AK 280890 V1.1 */ /* AK 070891 V1.3 */ /* AK V2.0 200298 */ /* input: INTEGER object integer output: PARTITION object [i] */ /* integer becomes a part of res */ /* integer >= 0 */ /* integer == 0 ==> part = [] */ { INT erg = OK; CTO(INTEGER,"b_i_pa",integer); if (S_I_I(integer) < 0) { erg += error("INTEGER < 0 in b_i_pa"); goto endr_ende; } erg += b_ks_pa(VECTOR,callocobject(),res); if (S_I_I(integer) > (INT)0) erg += b_o_v(integer,S_PA_S(res)); else { m_il_v((INT)0,S_PA_S(res)); freeall(integer); } ENDR("b_i_pa"); } INT m_ks_pa(kind,self,ergebnis) OP self,ergebnis; OBJECTKIND kind; /* make_kind.self_partition */ /* AK 300590 V1.1 */ /* AK 070891 V1.3 */ /* AK V2.0 200298 */ /* self and ergebnis may be equal */ { OP s = NULL; INT erg = OK; if (self != NULL) { s = callocobject(); erg += copy(self,s); } erg += b_ks_pa(kind,s,ergebnis); ENDR("m_ks_pa"); } INT b_ks_pa(kind,self,c) OP self,c; OBJECTKIND kind; /* build_kind_self_partition */ /* AK 060789 V1.0 */ /* AK 300590 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { OBJECTSELF d; INT erg = OK; d.ob_partition = callocpartition(); erg += b_ks_o(PARTITION, d, c); C_PA_K(c,kind); C_PA_S(c,self); ENDR("b_ks_pa"); } INT m_kl_pa(a,b,c) OBJECTKIND a; OP b,c; /* AK 060789 V1.0 */ /* AK 280890 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { return(b_ks_pa(a,callocobject(),c) || m_l_v(b,S_PA_S(c))); } INT b_kl_pa(a,b,c) OBJECTKIND a; OP b,c; /* AK 180893 */ /* AK V2.0 200298 */ { INT erg = OK; erg += b_ks_pa(a,callocobject(),c) ; erg += b_l_v(b,S_PA_S(c)); ENDR("b_kl_pa"); } INT dec_partition(a) OP a; /* AK 060789 V1.0 */ /* AK 261190 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ /* removes the biggest part of the partition */ /* stops if length = 0 */ { INT i; INT erg = OK; CTO(PARTITION,"dec_partition",a); if (S_PA_K(a) == VECTOR) { if (S_PA_LI(a) > (INT)0) erg += dec_vector(S_PA_S(a)); } else if (S_PA_K(a) == EXPONENT) { for(i=S_PA_LI(a)-1L;i>=(INT)0;i--) if (S_PA_II(a,i) > (INT)0) { erg += m_i_i(S_PA_II(a,i)-1L,S_PA_I(a,i)); goto endr_ende; } } else { erg += error("dec_partition:works only for VECTOR, EXPONENT"); } ENDR("dec_partition"); } INT lastof_partition(a,b) OP a,b; /* AK 060789 V1.0 */ /* AK 261190 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { INT erg = OK; CTO(PARTITION,"lastof_partition",a); if (S_PA_K(a) == VECTOR) { erg += lastof_vector(S_PA_S(a),b); if (EMPTYP(b)) erg += M_I_I(0,b); /* partition of weight 0 */ } else { erg += error("lastof_partition works only with VECTOR type partitions"); } ENDR("lastof_partition"); } INT length_partition(a,b) OP a,b; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ /* input: PARTITION object output: INTEGER object = number of parts of the partition */ { INT erg = OK; CTO(PARTITION,"length_partition",a); CE2(a,b,length_partition); if (S_PA_K(a) == VECTOR) erg += length_vector(S_PA_S(a),b); else if (S_PA_K(a) == EXPONENT) erg += sum_integervector(S_PA_S(a),b); else erg += error("length_partition: works only with VECTOR, EXPONENT partitions"); ENDR("length_partition"); } INT weight_partition(a,b) OP a,b; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ /* input: PARTITION object output: INTEGER object */ { INT i ,res=(INT)0; INT erg = OK; if (S_O_K(a) == CHARPARTITION) if (S_PA_K(a) == VECTOR) { for (i=S_PA_CL(a)-1L;i>=(INT)0;i--) res += S_PA_CII(a,i); M_I_I(res,b); goto endr_ende; } CTO(PARTITION,"weight_partition",a); if (S_PA_K(a) == VECTOR) { for (i=S_PA_LI(a)-1L;i>=(INT)0;i--) res += S_PA_II(a,i); erg += m_i_i(res,b); } else if (S_PA_K(a) == EXPONENT) { for (i=S_PA_LI(a)-1L;i>=(INT)0;i--) res += (i+1) * S_PA_II(a,i); erg += m_i_i(res,b); } else if (S_PA_K(a) == FROBENIUS) { OP c = callocobject(); erg += sum_integervector(S_V_I(S_PA_S(a),0),b); erg += sum_integervector(S_V_I(S_PA_S(a),1),c); erg += add_apply_integer(c,b); erg += freeall(c); erg += add_apply_integer(S_V_L(S_V_I(S_PA_S(a),0)),b); } else { erg += error("weight_partition: wrong kind of part"); } ENDR("weight_partition"); } INT scan_exponentpartition(c) OP c; /* AK V2.0 200298 */ { INT erg=OK; spa: erg += b_ks_pa(EXPONENT,callocobject(),c); erg += printeingabe("Please input a partition as vector"); erg += printeingabe("of integers (multiplicities) >= 0."); erg += scan(INTEGERVECTOR,S_PA_S(c)); if (partitionp(c) != TRUE) /* AK 170692 */ { erg += printeingabe("Sorry, you did not enter a partition"); erg += printeingabe("please try again."); erg += freeself(c); goto spa; } ENDR("scan_exponentpartition"); } INT scan_partition(c) OP c; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 250291 V1.2 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { INT erg=OK; spa: erg += b_ks_pa(VECTOR,callocobject(),c); erg += printeingabe("Please input a partition as increasing vector"); erg += printeingabe("of integers > 0."); erg += scan(INTEGERVECTOR,S_PA_S(c)); if (partitionp(c) != TRUE) /* AK 170692 */ { erg += printeingabe("Sorry, you did not enter a partition"); erg += printeingabe("please try again."); erg += freeself(c); goto spa; } ENDR("scan_partition"); } OP s_pa_s(a) OP a; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { OBJECTSELF c; c = s_o_s(a); return(c.ob_partition->pa_self); } OBJECTKIND s_pa_k(a) OP a; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { OBJECTSELF c; c = s_o_s(a); return(c.ob_partition->pa_kind); } OP s_pa_i(a,i) OP a; INT i; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { return(s_v_i(s_pa_s(a),i)); } INT s_pa_ii(a,i) OP a; INT i; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { INT erg = OK; CTO(PARTITION,"s_pa_ii",a); return(s_v_ii(s_pa_s(a),i)); ENDR("s_pa_ii"); } OP s_pa_l(a) OP a; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { INT erg = OK; CTO(PARTITION,"s_pa_l",a); return(s_v_l(s_pa_s(a))); ENDO("s_pa_l"); } INT s_pa_li(a) OP a; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ { INT erg = OK; CTO(PARTITION,"s_pa_li",a); return(s_v_li(s_pa_s(a))); ENDR("s_pa_li"); } INT c_pa_k(a,b) OP a; OBJECTKIND b; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { OBJECTSELF c; c = s_o_s(a); c.ob_partition->pa_kind = b; return(OK); } INT c_pa_s(a,b) OP a,b; /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { OBJECTSELF c; c = s_o_s(a); c.ob_partition->pa_self = b; return(OK); } INT objectread_partition(filename,part) OP part; FILE *filename; /* AK 291086 zum einlesen einer partition von einem file */ /* AK 060789 V1.0 */ /* AK 181289 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { INT kind; INT erg = OK; fscanf(filename,"%ld",&kind); erg += b_ks_pa((OBJECTKIND)kind, callocobject(),part); erg += objectread(filename,S_PA_S(part)); ENDR("objectread_partition"); } INT objectwrite_partition(filename,part) FILE *filename; OP part; /* AK 291086 */ /* zum schreiben einer partition auf einen file */ /* AK 060789 V1.0 */ /* AK 200690 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ { INT erg = OK; fprintf(filename,"%ld\n",(INT)PARTITION); fprintf(filename,"%ld\n",(INT)S_PA_K(part)); erg += objectwrite(filename,S_PA_S(part)); ENDR("objectwrite_partition"); } INT t_VECTOR_EXPONENT(von,nach) OP von,nach; /* AK 190588 */ /* AK 060789 V1.0 */ /* AK 200690 V1.1 */ /* AK 200891 V1.3 */ /* AK V2.0 020698 */ { INT i; OP l; INT erg = OK; PART_CHECK_KIND("t_EXPONENT_VECTOR",von,VECTOR); CE2(von,nach,t_VECTOR_EXPONENT); l=callocobject(); erg += weight(von,l); erg += b_ks_pa(EXPONENT,callocobject(),nach); erg += b_l_nv(l,S_PA_S(nach)); C_O_K(S_PA_S(nach),INTEGERVECTOR); for (i=(INT)0;i=(INT)0;i--) k = k + S_PA_II(a,i) - i; return M_I_I(k,b); } INT contain_comp_part(a,b) OP a,b; /* AK V2.0 090298 */ /* true if a sub b */ { INT i,j; if (S_PA_LI(a) > S_PA_LI(b)) return FALSE; for (i=0;i S_PA_II(b,S_PA_LI(b)-1-i)) return FALSE; } return TRUE; } INT sub_comp_part(a,b) OP a,b; /* returns 0 on equal 1 if a bigger according to containment -1 if smaller NONCOMPARABLE else */ /* AK V2.0 250298 */ /* a and b may be equal */ { INT erg=0,i,j; PART_CHECK_KIND("sub_comp_part",a,VECTOR); PART_CHECK_KIND("sub_comp_part",b,VECTOR); for (i=S_PA_LI(a)-1, j=S_PA_LI(b)-1;i>=0;i--,j--) { if (j<(INT)0) /* length of a > length of b */ { if (erg == -1) return NONCOMPARABLE; return 1; } if (S_PA_II(a,i) > S_PA_II(b,j)) { if (erg == -1) return NONCOMPARABLE; erg = 1; continue; } if (S_PA_II(a,i) < S_PA_II(b,j)) { if (erg == 1) return NONCOMPARABLE; erg = -1; continue; } } if (j >= 0) { return -1; } return erg; ENDR("sub_comp_part"); } INT dom_comp_part(a,b) OP a,b; /* returns 0 on equal 1 if a bigger according dominance -1 smaller NONCOMPARABLE if not comparable */ /* AK 140591 V1.2 */ /* AK 200891 V1.3 */ /* AK V2.0 200298 */ /* a and b may be equal */ { INT i,j,s1,s2; INT l,erg = (INT)0; PART_CHECK_KIND("dom_comp_part",a,VECTOR); PART_CHECK_KIND("dom_comp_part",b,VECTOR); l = (S_PA_LI(a) > S_PA_LI(b)) ? S_PA_LI(a) : S_PA_LI(b) ; /* l is the length of the longer partition */ for (i=(INT)0; i s2) erg = (INT)1; if (s1 < s2) erg = (INT)-1; } else if ( erg == 1L ) { if (s1 < s2) return NONCOMPARABLE; /* not comparable */ } else if ( erg == -1L ) { if (s1 > s2) return NONCOMPARABLE; /* not comparable */ } else { erg = error("dom_comp_part:internal error"); goto endr_ende; } } return erg; ENDR("dom_comp_part"); } INT even_partition(a,b) OP a,b; /* AK V2.0 200298 */ { OP c; INT erg; c = callocobject(); weight(a,c); sub(c,S_PA_L(a),c); erg = even(c); freeall(c); return erg; } INT random_part_EXPONENT(n,b) OP n,b; /* AK V2.0 250298 */ { return random_partition_exponent(n,b); } INT random_partition_exponent(n,b) OP n,b; /* new random partition nijnhuis wilf p.76 */ /* AK 151092 also for longint */ /* AK V2.0 200298 */ /* input: INTEGER object output: PARTITION object of given weight in EXPONENT notation */ { OP k,z,multi,p,d,m,i,isum,is,i1,j; INT nlast; INT erg = OK; CTO(INTEGER,"random_partition_exponent",n); CE2(n,b,random_partition_exponent); if (S_I_I(n) < (INT)0) { erg += error("random_partition_exponent: n < 0"); goto endr_ende; } else if (S_I_I(n) == (INT)0) { erg += first_part_EXPONENT(n,b); goto endr_ende; } multi=callocobject(); p=callocobject(); z=callocobject(); m=callocobject(); i=callocobject(); k=callocobject(); j=callocobject(); isum=callocobject(); is=callocobject(); i1=callocobject(); d=callocobject(); nlast = 0; erg += m_l_nv(n,multi); erg += m_l_v(n,p); /* l10: if (le(n,nlast)) goto l30; */ l10: if (S_I_I(n) <= nlast) goto l30; l20: erg += m_i_i(1L,S_V_I(p,(INT)0)); erg += m_i_i(nlast + (INT)1, m); /* erg += add(nlast,cons_eins,m); */ /* erg += copy_integer(n,nlast); */ nlast = S_I_I(n); if (S_I_I(n) == (INT)1) goto l30; for(copy(m,i); le(i,n); inc(i)) { erg += m_i_i((INT)0,isum); for (m_i_i(1L,d); le(d,i); inc_integer(d) ) { erg += m_i_i((INT)0,is); erg += copy(i,i1); l24: erg += sub(i1,d,i1); if (lt(i1,cons_null) ) goto l22; if (eq(i1,cons_null) ) goto l25; erg += add_apply(S_V_I(p,S_I_I(i1)-1L),is); goto l24; l25: erg += inc(is); l22: erg += mult_apply(d,is); erg += add_apply(is,isum); } erg += ganzdiv(isum,i,S_V_I(p,S_I_I(i)-1L)); } l30: erg += copy(n,m); erg += m_i_i((INT)0,k); l40: erg += mult(m,S_V_I(p,S_I_I(m)-1L),d); erg += random_integer(z,cons_eins,d); erg += m_i_i((INT)0,d); l110: erg += inc(d); l60: erg += copy(m,i1); erg += m_i_i((INT)0,j); l150: erg += inc(j); l70: erg += sub(i1,d,i1); l80: if (lt(i1,cons_null)) goto l110; if (eq(i1,cons_null)) goto l90; erg += mult(d,S_V_I(p,S_I_I(i1)-1),is); erg += sub(z,is,z); l130: if (le(z,cons_null)) goto l145; goto l150; l90: erg += sub(z,d,z); l100: if (le(z,cons_null)) goto l145; goto l110; l145: erg += add_apply(j,S_V_I(multi,S_I_I(d)-1L)); erg += add_apply(j,k); l160: erg += copy(i1,m); l170: if (neq(m,cons_null)) goto l40; erg+=freeall(z); erg+=freeall(k); erg+=freeall(m); erg+=freeall(p); erg+=freeall(i); erg+=freeall(i1); erg+=freeall(j); erg+=freeall(is); erg+=freeall(isum); erg+=freeall(d); erg += b_ks_pa(EXPONENT,multi,b); /* do not free multi */ ENDR("random_partition_exponent"); } INT random_partition(n,p) OP n,p; /* AK 230298 V2.0 */ /* input: INTEGER object n output: PARTITION object of given weight in VECTOR notation */ /* n and p may be equal */ { OP c; INT erg = OK; CTO(INTEGER,"random_partition",n); if (S_I_I(n) < (INT)0) { erg += error("random_partition: n < 0"); goto endr_ende; } else if (S_I_I(n) < (INT)2) { erg += first_partition(n,p); goto endr_ende; } c = callocobject(); erg += random_partition_exponent(n,c); erg += t_EXPONENT_VECTOR(c,p); erg += freeall(c); ENDR("random_partition"); } INT t_VECTOR_FROBENIUS(a,b) OP a,b; /* AK V2.0 250298 */ { return t_VECTOR_FROB(a,b); } INT t_VECTOR_FROB(a,b) OP a,b; /* AK 101292 */ /* AK V2.0 200298 */ { INT i,j; INT erg = OK; OP c; PART_CHECK_KIND("t_VECTOR_FROB",a,VECTOR); CE2(a,b,t_VECTOR_FROB); erg += b_ks_pa(FROBENIUS,callocobject(),b); erg += m_il_v(2L,S_PA_S(b)); if (S_PA_LI(a) == (INT)0) { erg += m_il_v((INT)0,S_V_I(S_PA_S(b),(INT)0)); erg += m_il_v((INT)0,S_V_I(S_PA_S(b),1L)); goto endr_ende; } for (i=(INT)0, j=S_PA_LI(a)-1L;S_PA_II(a,j) > i; i++,j--) ; erg += m_il_v(i,S_V_I(S_PA_S(b),(INT)0)); erg += m_il_v(i,S_V_I(S_PA_S(b),1L)); c = callocobject(); erg += conjugate(a,c); for (j=(INT)0;j0) { if(i==d-1) return 0; if(x>=pdc[i]) { v[i]=pdc[i]; x -= pdc[i--]; } else { v[i] = x; x = 0; } } return 1; } /********************************************************************** * partitions avec contraintes * **********************************************************************/ static int repartir(aa,rang,contrib,pdc,v,lv,dd,e) OP dd,e; int rang, contrib, lv, pdc[], v[]; struct axelclaude *aa; { int d,l,x,i; int *w, *pdcv; pdcv = (int *) SYM_calloc(lv,sizeof(int)); w = (int *) SYM_calloc(lv,sizeof(int)); d=1; l=lv-1; while(1) { remplir(contrib,pdc,v,d,l); utiliser(aa,rang,v,lv,dd,e); if(rangnbl-1) { for(i=1;i<=l;i++) pdcv[i]=pdc[i]-v[i]; repartir(aa,rang+1,aa->pdl[rang+1],pdcv,w,lv,dd,e); } i=l-1; contrib = v[l]; while(i>0) if(v[i]==pdc[i]) contrib += v[i--]; else if(contrib==0) contrib=v[i--]; else break; if(i>0) { v[i]++; contrib--; d=i+1; continue; } else break; } SYM_free(pdcv); SYM_free(w); } /******************************************************************* * exploitation d'une ligne construite * *******************************************************************/ static int utiliser(aa,rang,v,lv,d,e) OP d,e; struct axelclaude *aa; int v[], lv; { int i, j; /* for(i=1;imat[rang][i]=v[i]; */ for(i=1;imat[(rang*aa->nbc) +i]=v[i]; if(rang==aa->nbl-1) { inc(e); for(i=1;inbl;i++) { for(j=1;jmat[(i*aa->nbc) +j],S_M_IJ(d,i-1,j-1) ); } copy(d,S_V_I(e,S_V_LI(e)-1)); } } INT sscan_partition(t,a) OP a; char *t; /* AK 050194 to read partition from string format [1,2,3,23,23,33] */ /* AK 230298 V2.0 */ { INT i,n,erg = OK; char *v,*w; v = t; while (*v == ' ') v++; if (*v != '[') {erg = ERROR; goto spe;} w = v; n = (INT)1; /* now we count the number of parts */ w++; while (*w != ']') { if (*w == ',') n++; else if (not SYM_isdigit(*w)) {erg = ERROR; goto spe;} w++; } /* n is the number of parts */ b_ks_pa(VECTOR,callocobject(),a); m_il_v(n,S_PA_S(a)); w = v; w++; for (i=(INT)0; i= b equal parts */ /* AK 230298 V2.0 */ { INT erg = OK; INT i,j=0L,k=0L; CTO( PARTITION,"equal_parts",a); CTO( INTEGER,"equal_parts",b); if (S_I_I(b) <= (INT)0) { erg += error("equal_parts:integer object not bigger 0"); goto endr_ende; } if (S_PA_K(a) == EXPONENT) { for (i=0;i= S_I_I(b)) return TRUE; return FALSE; } if (S_PA_K(a) != VECTOR) { erg += error("equal_parts: partition object not VECTOR kind"); goto endr_ende; } for (i=0L;i= S_PA_LI(a)) return copy(a,c); if (j >= S_PA_II(a,S_PA_LI(a)-1L-i)) return copy(a,c); d = callocobject(); erg += copy(S_PA_S(a),d); m_i_i(j,S_V_I(d,S_PA_LI(a)-i-1)); for (k=i+1L; k= j) { erg += dec(S_V_I(d,S_PA_LI(a)-1L-k)); erg += copy(S_V_I(d,S_PA_LI(a)-1L-k),S_V_I(d,S_PA_LI(a)-k)); } else { m_i_i(j,S_V_I(d,S_PA_LI(a)-k)); break; } if (k == S_PA_LI(a)) m_i_i(j,S_V_I(d,0L)); erg += m_v_pa(d,c); erg += freeall(d); ENDR("remove_hook"); } INT p_hook_diagramm(a,b,c) OP a,b,c; /* AK 010295 */ /* AK 230298 V2.0 */ /* input: PARTITION object a INTEGER object b output: hook diagramm with entry = hooklength mod b */ { INT erg=OK,i,j,k,l; CTO(INTEGER,"p_hook_diagramm",b); PART_CHECK_KIND("p_hook_diagramm",a,VECTOR); CE3(a,b,c,p_hook_diagramm); if (S_I_I(b) < (INT) 0) { erg += error("p_hook_diagramm: second parameter < 0"); goto endr_ende; } erg += hook_diagramm(a,c); if (S_I_I(b) == (INT)0) goto ee; if (S_I_I(b) == (INT)1) goto ee; for (i=0L;i0;j--) { erg += m_i_i(k,S_V_I(c,l)); l++; } } } erg += m_v_pa(c,b); erg += freeall(c); ENDR("strict_to_odd_part"); } INT nachfolger_young(a,b) OP a,b; /* input: PARTITION object a output: VECTOR object of PARTITION objects, which are bigger neighbours in the Young poset */ /* AK V2.0 170298 */ /* a and b may be equal */ { INT erg = OK,k; OP c,z; CTO(PARTITION,"nachfolger_young",a); c = callocobject(); erg += first_partition(cons_eins,c); erg += outerproduct_schur(c,a,c); k=0; z = c; while (z != NULL) { k++; z = S_L_N(z); } erg += m_il_v(k,b); k=0; z = c; while (z != NULL) { erg += copy_partition(S_S_S(z), S_V_I(b,k)); k++; z = S_L_N(z); } erg += freeall(c); ENDR("nachfolger_young"); } INT vorgaenger_young(a,b) OP a,b; /* input: PARTITION object a output: VECTOR object of PARTITION objects, which are smaller neighbours in the Young poset */ /* AK V2.0 170298 */ /* a and b may be equal */ { INT erg = OK,k; OP c,z; CTO(PARTITION,"vorgaenger_young",a); c = callocobject(); erg += first_partition(cons_eins,c); erg += part_part_skewschur(a,c,c); k=0; z = c; while (z != NULL) { k++; z = S_L_N(z); } erg += m_il_v(k,b); k=0; z = c; while (z != NULL) { erg += copy_partition(S_S_S(z), S_V_I(b,k)); k++; z = S_L_N(z); } erg += freeall(c); ENDR("vorgaenger_young"); } INT character_polynom(a,b) OP a,b; /* AK 040892 */ { INT erg = OK; INT i,wi; OP l,lp,p,res,v; PART_CHECK_KIND("character_polynom",a,VECTOR); if (S_PA_LI(a) == (INT)0) { erg += m_scalar_polynom(cons_eins,b); goto endr_ende; } C1R(a,"character_polynom",b); l = callocobject(); lp = callocobject(); p = callocobject(); v = callocobject(); erg += copy(S_PA_L(a),l); erg += inc(l); erg += copy(a,lp); erg += first_permutation(l,p); erg += young_polynom(a,b); while (next(p,p)) { erg += copy(S_PA_S(a),v); for (i=1L;i(INT)0) { erg += m_i_i(k,d); erg += multinom(d,c,e); erg += m_iindex_monom(i,f); erg += binom(f,d,m); erg += mult_apply(e,m); erg += mult_apply(m,n); } } erg += add(n,l,l); j=(INT)0; if (S_V_LI(b) == 0) break; /* AK 060498 */ while (not next(S_V_I(b,j),S_V_I(b,j))) { j++; if (j==S_V_LI(b)) break; } if (j == S_V_LI(b)) break; /* links von der stelle wo erhoeht wurd muss auf null gesetzt werden */ for (j--;j>=(INT)0;j--) erg += first_part_EXPONENT(S_PA_I(a,j),S_V_I(b,j)); } while(1); /* alle partitionen durchlaufen */ erg += freeall(b); erg += freeall(e); erg += freeall(m); erg += freeall(n); erg += freeall(f); erg += freeall(d); erg += freeall(c); /* erg += inc(young_ls); erg += inc(young_ps); erg += copy(a,S_V_I(young_ls,S_V_LI(young_ls)-1L)); erg += copy(l,S_V_I(young_ps,S_V_LI(young_ls)-1L)); youngende: */ S1R(a,"young_polynom",l); ENDR("young_polynom"); } #endif /* PARTTRUE */ #ifdef PARTTRUE #endif /* PARTTRUE */ #undef callocobject