bridge/class-master/depend/pari/src/basemath/qfisom.c
/* The Bacher-polynomial for v[I] with scalar product S is
 * defined as follows: let list be the vectors which have the same length as
 * v[I] and with scalar product S with v[I], for each vector w in list let n_w
 * be the number of pairs (y,z) of vectors in list, such that all scalar
 * products between w,y and z are S, then the Bacher-polynomial is the sum over
 * the w in list of the monomials X^n_w  */
The Bacher-polynomial for v[I] with scalar product S is
defined as follows: let list be the vectors which have the same length as
v[I] and with scalar product S with v[I], for each vector w in list let n_w
be the number of pairs (y,z) of vectors in list, such that all scalar
products between w,y and z are S, then the Bacher-polynomial is the sum over
the w in list of the monomials X^n_w
The Bacher - polynomial for v [ I ] with scalar product S is defined as follows : let list be the vectors which have the same length as v [ I ] and with scalar product S with v [ I ] for each vector w in list let n_w be the number of pairs ( y z ) of vectors in list such that all scalar products between w y and z are S then the Bacher - polynomial is the sum over the w in list of the monomials X^n_w
static GEN
bacher(long I, long S, struct qfauto *qf)
{
  pari_sp av=avma;
  GEN V=qf->V, W=qf->W, Fv=gel(qf->v,1);
  GEN  list, listxy, counts, vI;
  long i, j, k, nlist, nxy;
  long n = lg(V)-1;
  long sum, mind, maxd;
  GEN coef;
  I = labs(I);
  vI = gel(V,I);
  list = zero_Flv(2*n);
  nlist = 0;
  for (i = 1; i <= n; ++i)
    if (mael(W,i,1) == mael(W,I,1))
    {
      long s = zv_dotproduct(vI, gel(Fv,i));
      if (s == S)
        list[++nlist] = i;
      if (-s == S)
        list[++nlist] = -i;
    }
  sum = nlist;
  if (nlist==0) retmkvec2(mkvecsmall3(0,0,0),cgetg(1,t_VEC));
  counts = cgetg(nlist+1, t_VECSMALL);
  listxy = cgetg(nlist+1, t_VECSMALL);
  for (i = 1; i <= nlist; ++i)
  {
    long S1;
    for (j = 1; j <= nlist; ++j)
      listxy[j] = 0;
    nxy = 0;
    S1 = list[i] > 0 ? S : -S;
    for (j = 1; j <= nlist; ++j)
    {
      long S2 = list[j] > 0 ? S1 : -S1;
      if (zv_dotproduct(gel(V,labs(list[i])), gel(Fv,labs(list[j]))) == S2)
        listxy[++nxy] = list[j];
    }
    counts[i] = 0;
    for (j = 1; j <= nxy; ++j)
    {
      long S1 = listxy[j] > 0 ? S : -S;
      for (k = j+1; k <= nxy; ++k)
      {
        long S2 = listxy[k] > 0 ? S1 : -S1;
        long lj = labs(listxy[j]), lk = labs(listxy[k]);
        if (zv_dotproduct(gel(V,lj), gel(Fv,lk)) == S2)
          counts[i] += 1;
      }
    }
  }
  maxd = counts[1];
  mind = counts[1];
  for (i = 2; i <= nlist; ++i)
  {
    if (counts[i] > maxd)
      maxd = counts[i];
    else if (counts[i] < mind)
      mind = counts[i];
  }
  coef = zero_Flv(maxd - mind + 1);
  for (i = 1; i <= nlist; ++i)
    coef[1+counts[i] - mind] += 1;
  if (DEBUGLEVEL)
    err_printf("QFIsom: mind=%ld maxd=%ld sum=%ld\n",mind,maxd,sum);
  return gerepilecopy(av, mkvec2(mkvecsmall3(sum, mind, maxd),coef));
}
static GEN bacher ( long I , long S , struct qfauto * qf ) { pari_sp av = avma ; GEN V = qf -> V , W = qf -> W , Fv = gel ( qf -> v , 1 ) ; GEN list , listxy , counts , vI ; long i , j , k , nlist , nxy ; long n = lg ( V ) - 1 ; long sum , mind , maxd ; GEN coef ; I = labs ( I ) ; vI = gel ( V , I ) ; list = zero_Flv ( 2 * n ) ; nlist = 0 ; for ( i = 1 ; i <= n ; ++ i ) if ( mael ( W , i , 1 ) == mael ( W , I , 1 ) ) { long s = zv_dotproduct ( vI , gel ( Fv , i ) ) ; if ( s == S ) list [ ++ nlist ] = i ; if ( - s == S ) list [ ++ nlist ] = - i ; } sum = nlist ; if ( nlist == 0 ) retmkvec2 ( mkvecsmall3 ( 0 , 0 , 0 ) , cgetg ( 1 , t_VEC ) ) ; counts = cgetg ( nlist + 1 , t_VECSMALL ) ; listxy = cgetg ( nlist + 1 , t_VECSMALL ) ; for ( i = 1 ; i <= nlist ; ++ i ) { long S1 ; for ( j = 1 ; j <= nlist ; ++ j ) listxy [ j ] = 0 ; nxy = 0 ; S1 = list [ i ] > 0 ? S : - S ; for ( j = 1 ; j <= nlist ; ++ j ) { long S2 = list [ j ] > 0 ? S1 : - S1 ; if ( zv_dotproduct ( gel ( V , labs ( list [ i ] ) ) , gel ( Fv , labs ( list [ j ] ) ) ) == S2 ) listxy [ ++ nxy ] = list [ j ] ; } counts [ i ] = 0 ; for ( j = 1 ; j <= nxy ; ++ j ) { long S1 = listxy [ j ] > 0 ? S : - S ; for ( k = j + 1 ; k <= nxy ; ++ k ) { long S2 = listxy [ k ] > 0 ? S1 : - S1 ; long lj = labs ( listxy [ j ] ) , lk = labs ( listxy [ k ] ) ; if ( zv_dotproduct ( gel ( V , lj ) , gel ( Fv , lk ) ) == S2 ) counts [ i ] += 1 ; } } } maxd = counts [ 1 ] ; mind = counts [ 1 ] ; for ( i = 2 ; i <= nlist ; ++ i ) { if ( counts [ i ] > maxd ) maxd = counts [ i ] ; else if ( counts [ i ] < mind ) mind = counts [ i ] ; } coef = zero_Flv ( maxd - mind + 1 ) ; for ( i = 1 ; i <= nlist ; ++ i ) coef [ 1 + counts [ i ] - mind ] += 1 ; if ( DEBUGLEVEL ) err_printf ( " \n " , mind , maxd , sum ) ; return gerepilecopy ( av , mkvec2 ( mkvecsmall3 ( sum , mind , maxd ) , coef ) ) ; }
The Bacher-polynomial for v[I] with scalar product S is
 defined as follows: let list be the vectors which have the same length as
 v[I] and with scalar product S with v[I], for each vector w in list let n_w
 be the number of pairs (y,z) of vectors in list, such that all scalar
 products between w,y and z are S, then the Bacher-polynomial is the sum over
 the w in list of the monomials X^n_w
The Bacher - polynomial for v [ I ] with scalar product S is defined as follows : let list be the vectors which have the same length as v [ I ] and with scalar product S with v [ I ] for each vector w in list let n_w be the number of pairs ( y z ) of vectors in list such that all scalar products between w y and z are S then the Bacher - polynomial is the sum over the w in list of the monomials X^n_w
/* the Bacher-polynomials of v[I] and -v[I] are equal */ /* list of vectors that have scalar product S with v[I] */ /* there are nlist vectors that have scalar product S with v[I] */ /* listxy is the list of the nxy vectors from list that have scalar
       product S with v[list[i]] */ /* note: for i > 0 is v[-i] = -v[i] */ /* counts[i] is the number of pairs for the vector v[list[i]] */ /* maxd is the maximal degree of the Bacher-polynomial,
      mind the minimal degree */ /* the Bacher-polynomial is now: sum from i=mind to maxd over
     coef[i - mind] * X^i */