GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include"typedef.h"1#include"matrix.h"2#include"longtools.h"3#include"polyeder.h"4/**************************************************************************\5@---------------------------------------------------------------------------6@---------------------------------------------------------------------------7@ FILE: refine_polyeder.c8@---------------------------------------------------------------------------9@---------------------------------------------------------------------------10@11\**************************************************************************/121314static int g_option;1516static void re_sort(F,old_no, count, test, l)17polyeder_TYP *F;18int old_no, *test, l;19int *count;20{21int i;22int d=0;23for(i=0;i<old_no;i++)24{25if(count[i]< 0)26free_vertex(&(F->vert[i]));27}28for(i=0;d<F->vert_no;i++)29{30while(d<F->vert_no && F->vert[d] == NULL)31d++;32if(d != i)33{34F->vert[i] = F->vert[d];35F->vert[d] = NULL;36}37d++;38}39while(F->vert[i-1] == NULL)40i--;41F->vert_no = i;4243d=0;44for(i=0;i<F->wall_no;i++)45{46if(test[i] == -1)47free_wall(&(F->wall[i]));48}49for(i=0;d<F->wall_no;i++)50{51while(d<F->wall_no && F->wall[d] == NULL)52d++;53if(d!= i)54{55F->wall[i] = F->wall[d];56F->wall[d] = NULL;57}58d++;59}60F->wall_no = i;61}626364static void renumerate(v,test)65vertex_TYP *v;66int *test;67{68int i,a;69for(i=0;i<v->wall_no;i++)70{71a = v->wall[i];72v->wall[i] = test[a];73}74}757677static void add_wall_to_vertex(i, v)78int i;79vertex_TYP *v;80{81if(v->wall_SIZE == 0)82{83v->wall = (int *)malloc(extsize1 *sizeof(int));84v->wall_SIZE = extsize1;85}86if(v->wall_no == v->wall_SIZE)87{88v->wall_SIZE += extsize1;89v->wall = (int *)realloc(v->wall,v->wall_SIZE *sizeof(int));90}91v->wall[v->wall_no] = i;92v->wall_no++;93}949596static void delete_walls_from_vertex(v, test)97vertex_TYP *v;98int *test;99{100int i,d;101102d=0;103for(i=0; d<v->wall_no;i++)104{105while(d< v->wall_no && test[v->wall[d]] == -1)106d++;107v->wall[i] = v->wall[d];108d++;109}110v->wall_no = i;111}112113114115static void add_wall_to_polyeder(F, w)116polyeder_TYP *F;117wall_TYP *w;118{119if(F->wall_SIZE == 0)120{121F->wall = (wall_TYP **)malloc(extsize1 *sizeof(wall_TYP *));122F->wall_SIZE = extsize1;123}124if(F->wall_no == F->wall_SIZE)125{126F->wall_SIZE += extsize1;127F->wall = (wall_TYP **)realloc(F->wall,F->wall_SIZE *sizeof(wall_TYP *));128}129F->wall[F->wall_no] = copy_wall(w);130F->wall_no++;131}132133134135static void add_vertex_to_polyeder(F, w)136polyeder_TYP *F;137vertex_TYP *w;138{139if(F->vert_SIZE == 0)140{141F->vert = (vertex_TYP **)malloc(extsize1 *sizeof(vertex_TYP *));142F->vert_SIZE = extsize1;143}144if(F->vert_no == F->vert_SIZE)145{146F->vert_SIZE += extsize1;147F->vert = (vertex_TYP **)realloc(F->vert,F->vert_SIZE *sizeof(vertex_TYP *));148}149F->vert[F->vert_no] = w;150F->vert_no++;151}152153154static vertex_TYP *gis_neighbour(i,j,F)155int i,j;156polyeder_TYP *F;157{158int k,l,m;159int a, u, tester1;160int anz;161vertex_TYP *erg;162matrix_TYP *A;163164165k=F->vert[j]->wall_no;166if(k>F->vert[i]->wall_no)167k=F->vert[i]->wall_no;168erg = init_vertex(F->vert[0]->dim, k+1);169anz=0;170u=0;171for(k=0;k<F->vert[i]->wall_no;k++)172{173a = F->vert[i]->wall[k];174for(l=u; l<F->vert[j]->wall_no && F->vert[j]->wall[l]< a; l++);175u=l;176if(u<F->vert[j]->wall_no && F->vert[j]->wall[u] == a)177{ erg->wall[anz] = a; anz++;}178}179erg->wall_no = anz;180if(anz < F->vert[0]->dim-2)181{ free_vertex(&erg); erg=NULL; return(NULL);}182183A = init_mat(anz,F->vert[0]->dim, "l");184for(k=0;k<anz;k++)185for(l=0; l<F->vert[0]->dim;l++)186A->array.SZ[k][l] = F->wall[erg->wall[k]]->gl[l];187a = long_row_gauss(A);188free_mat(A);189if(a < F->vert[0]->dim-2)190{ free_vertex(&erg); erg=NULL; return(NULL);}191return(erg);192}193194195196static vertex_TYP *is_neighbour(i,j,F, vertex_no)197int i,j;198polyeder_TYP *F;199int vertex_no;200{201int k,l,m;202int a, u, tester1;203int anz;204vertex_TYP *erg;205206207k=F->vert[j]->wall_no;208if(k>F->vert[i]->wall_no)209k=F->vert[i]->wall_no;210erg = init_vertex(F->vert[0]->dim, k+1);211anz=0;212u=0;213for(k=0;k<F->vert[i]->wall_no;k++)214{215a = F->vert[i]->wall[k];216for(l=u; l<F->vert[j]->wall_no && F->vert[j]->wall[l]< a; l++);217u=l;218if(u<F->vert[j]->wall_no && F->vert[j]->wall[u] == a)219{ erg->wall[anz] = a; anz++;}220}221erg->wall_no = anz;222if(anz < F->vert[0]->dim-2)223{ free_vertex(&erg); erg=NULL; return(NULL);}224225for(k=0; k<vertex_no ;k++)226{227if(k != i && k != j)228{229tester1 = TRUE;230u=0;231for(l=0; l<anz && tester1 == TRUE; l++)232{233a = erg->wall[l];234m=u;235while(m<F->vert[k]->wall_no && F->vert[k]->wall[m] <a)236m++;237if(m == F->vert[k]->wall_no || F->vert[k]->wall[m] != a)238tester1 = FALSE;239u=m;240}241if(tester1 == TRUE)242{ free_vertex(&erg); erg=NULL; return(NULL);}243}244}245return(erg);246}247248249250251/**************************************************************************\252@---------------------------------------------------------------------------253@ int refine_polyeder(F, h)254@ polyeder_TYP *F;255@ wall_TYP *h;256@257@ calculates the intersection of the linear Polyeder 'F' with the halfspace258@ defined by the inequality259@ H := h->gl * X^{tr} >= 0260@ and stores it in F.261@ If the intersection of F and H is already F, 'refine_polyeder returns 0,262@ otherwise 1.263@ All vertices of the intersecting polyeder are calculated.264@ If the intersection has not full dimension, i.e the new Polyeder is265@ non-degenerate, F->is_denerate is set to 0.266@267@ CAUTION: The result is correct only if the new Polyeder is non-degenerate.268@269@---------------------------------------------------------------------------270@271\**************************************************************************/272int refine_polyeder(F, h)273polyeder_TYP *F;274wall_TYP *h;275{276int i,j,k;277int l;278int old_no;279int *count;280int waste;281int tester, *test;282int anz;283int p,n, z;284vertex_TYP *v;285int *wall_test, *necessary;286287288289p=0;n=0;290old_no = F->vert_no;291count = (int *)malloc(F->vert_no *sizeof(int *));292for(i=0;i<F->vert_no;i++)293count[i] = 0;294for(i=0;i<old_no;i++)295{296count[i] = wall_times_vertex(h,F->vert[i]);297if(count[i] > 0)298p++;299if(count[i] < 0)300n++;301if(count[i] == 0)302z++;303}304if(n == 0)305{306free(count);307return(0);308}309if(p == 0)310{311F->is_degenerate = TRUE;312}313314315g_option = FALSE;316if(is_option('g') == TRUE)317g_option = TRUE;318wall_test = (int *)malloc(F->wall_no *sizeof(int));319for(i=0;i<F->wall_no;i++)320wall_test[i] = 2;321for(i=0;i<old_no;i++)322{323if(count[i]>0)324{325for(j=0;j<F->vert[i]->wall_no;j++)326{327if(wall_test[F->vert[i]->wall[j]] == 2)328wall_test[F->vert[i]->wall[j]] = 1;329if(wall_test[F->vert[i]->wall[j]] == -1)330wall_test[F->vert[i]->wall[j]] = 0;331}332}333if(count[i] < 0)334{335for(j=0;j<F->vert[i]->wall_no;j++)336{337if(wall_test[F->vert[i]->wall[j]] == 2)338wall_test[F->vert[i]->wall[j]] = -1;339if(wall_test[F->vert[i]->wall[j]] == 1)340wall_test[F->vert[i]->wall[j]] = 0;341}342}343}344necessary = (int *)malloc(F->vert_no *sizeof(int));345for(i=0;i<old_no;i++)346necessary[i] = FALSE;347for(i=0;i<old_no;i++)348{349if(count[i] != 0)350{351k=0;352for(j=0;j<F->vert[i]->wall_no && necessary[i] == FALSE;j++)353{354if( wall_test[F->vert[i]->wall[j]] == 0)355k++;356if(k>= F->vert[i]->dim-2)357{358if(count[i] > 0)359necessary[i] = 1;360if(count[i] < 0)361necessary[i] = -1;362if(count[i] == 0)363necessary[i] = 0;364}365}366}367}368369if(F->vert[0]->dim == 2)370{371for(i=0;i<old_no;i++)372{373if(count[i] > 0)374necessary[i] = 1;375if(count[i] < 0)376necessary[i] = -1;377if(count[i] == 0)378necessary[i] = 0;379}380}381382383for(i=0;i<old_no;i++)384{385if(necessary[i] == -1)386{387for(j=0;j<old_no;j++)388{389if(necessary[j] == 1)390{391if(g_option == TRUE)392v = gis_neighbour(i, j, F);393else394v = is_neighbour(i, j, F, old_no);395if(v != NULL)396{397for(k=0; k<v->dim; k++)398v->v[k] = count[j] * F->vert[i]->v[k] - count[i] *F->vert[j]->v[k];399normal_vertex(v);400add_vertex_to_polyeder(F, v);401}402}403}404}405}406add_wall_to_polyeder(F, h);407test = (int *)malloc((F->wall_no) *sizeof(int));408l=0;409for(i=0; i<F->wall_no-1;i++)410{411tester = 0;412for(j=0;j<old_no && tester == 0; j++)413{414if(count[j] > 0)415if(is_vertex_of_wallno(F->vert[j], i) == TRUE)416tester = 1;417}418if(tester == 0)419test[i] = -1;420else421{test[i] = l; l++;}422}423test[F->wall_no-1] = l;424l++;425if(test[0] == -1)426F->is_closed = TRUE;427428for(i=0;i<old_no; i++)429{430if(count[i] == 0)431add_wall_to_vertex(F->wall_no-1, F->vert[i]);432}433434for(i=0;i<old_no;i++)435{436if(count[i]==0)437delete_walls_from_vertex(F->vert[i],test);438if(count[i]>=0)439renumerate(F->vert[i],test);440}441for(i=old_no; i<F->vert_no;i++)442{443F->vert[i]->wall[F->vert[i]->wall_no] = F->wall_no-1;444F->vert[i]->wall_no++;445renumerate(F->vert[i],test);446}447448re_sort(F, old_no, count, test,l);449450free(count);451free(test);452free(necessary);453free(wall_test);454return(1);455}456457458