bridge/class-master/depend/pari/src/basemath/volcano.c
/*
 * This is Sutherland 2009 Algorithm Descend (p12).
 */
This is Sutherland 2009 Algorithm Descend (p12).
This is Sutherland 2009 Algorithm Descend ( p12 ) .
ulong
descend_volcano(GEN phi, ulong j, ulong p, ulong pi,
  long level, long L, long depth, long steps)
{
  pari_sp ltop = avma;
  GEN path_g;
  ulong *path, res;
  long max_len;
  if (steps <= 0 || level + steps > depth) pari_err_BUG("descend_volcano");
  max_len = depth - level;
  path_g = cgetg(max_len + 1 + 1, t_VECSMALL);
  path = zv_to_ulongptr(path_g);
  path[0] = j;
  if (!level)
  {
    GEN nhbrs = Flx_roots(Flm_Fl_polmodular_evalx(phi, L, j, p, pi), p);
    long i;
    for (i = 1; i <= 3; i++)
    {
      long len;
      path[1] = nhbrs[i];
      len = extend_path(path, phi, p, pi, L, max_len);
      if (len < max_len || node_degree(phi, L, path[len], p, pi) == 1) break;
    }
    if (i > 3) pari_err_BUG("descend_volcano [2]");
  }
  else
  {
    ulong nhbr1, nhbr2;
    long len;
    random_distinct_neighbours_of(&nhbr1, &nhbr2, phi, j, p, pi, L, 1);
    path[1] = nhbr1;
    len = extend_path(path, phi, p, pi, L, max_len);
    if (len == max_len   
        && (is_j_exceptional(path[len], p)
            || node_degree(phi, L, path[len], p, pi) != 1)) {
      path[1] = nhbr2;
      (void) extend_path(path, phi, p, pi, L, steps);
    }
  }
  res = path[steps]; avma = ltop; return res;
}
ulong descend_volcano ( GEN phi , ulong j , ulong p , ulong pi , long level , long L , long depth , long steps ) { pari_sp ltop = avma ; GEN path_g ; ulong * path , res ; long max_len ; if ( steps <= 0 || level + steps > depth ) pari_err_BUG ( " " ) ; max_len = depth - level ; path_g = cgetg ( max_len + 1 + 1 , t_VECSMALL ) ; path = zv_to_ulongptr ( path_g ) ; path [ 0 ] = j ; if ( ! level ) { GEN nhbrs = Flx_roots ( Flm_Fl_polmodular_evalx ( phi , L , j , p , pi ) , p ) ; long i ; for ( i = 1 ; i <= 3 ; i ++ ) { long len ; path [ 1 ] = nhbrs [ i ] ; len = extend_path ( path , phi , p , pi , L , max_len ) ; if ( len < max_len || node_degree ( phi , L , path [ len ] , p , pi ) == 1 ) break ; } if ( i > 3 ) pari_err_BUG ( " " ) ; } else { ulong nhbr1 , nhbr2 ; long len ; random_distinct_neighbours_of ( & nhbr1 , & nhbr2 , phi , j , p , pi , L , 1 ) ; path [ 1 ] = nhbr1 ; len = extend_path ( path , phi , p , pi , L , max_len ) ; if ( len == max_len && ( is_j_exceptional ( path [ len ] , p ) || node_degree ( phi , L , path [ len ] , p , pi ) != 1 ) ) { path [ 1 ] = nhbr2 ; ( void ) extend_path ( path , phi , p , pi , L , steps ) ; } } res = path [ steps ] ; avma = ltop ; return res ; }
This is Sutherland 2009 Algorithm Descend (p12).
This is Sutherland 2009 Algorithm Descend ( p12 ) .
/* level = 0 means we're on the volcano surface... */ /* Look for any path to the floor. One of j's first three neighbours leads
     * to the floor, since at most two neighbours are on the surface. */ /* If nhbrs[i] took us to the floor: */ /* If last j isn't on the floor */ /* Ended up on the surface. */ /* The other neighbour leads to the floor */