void test1836 ( )

/******************************************************************************/
/*
  Purpose:

    TEST1836 tests SPHERE_EXP2IMP_ND.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    26 July 2011

  Author:

    John Burkardt
*/
{
# define N 3

  int n = N;
  double p[N*(N+1)] = {
    4.0, 2.0, 3.0, 
    1.0, 5.0, 3.0, 
    1.0, 2.0, 6.0, 
   -2.0, 2.0, 3.0 };
  double pc[N];
  double pc_true[N] = { 1.0, 2.0, 3.0 };
  double r;
  double r_true = 3.0;

  printf ( "\n" );
  printf ( "TEST1836\n" );
  printf ( "  SPHERE_EXP2IMP_ND: explicit sphere => implicit form;\n" );

  r8mat_transpose_print ( n, n + 1, p, "  Initial form of explicit sphere:" );

  sphere_exp2imp_nd ( n, p, &r, pc );

  printf ( "\n" );
  printf ( "  Computed form of implicit sphere:\n" );
  printf ( "\n" );
  printf ( "  Imputed radius = %f\n", r );
  printf ( "  True radius =    %f\n", r_true );

  r8vec_print ( n, pc, "  Imputed center" );

  r8vec_print ( n, pc_true, "  True center" );

  return;
# undef N
}
void test02 ( void )

/******************************************************************************/
/*
  Purpose:

    TEST02 prints the data for each problem.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    06 February 2012

  Author:

    John Burkardt
*/
{
  int data_num;
  int dim_num;
  double *p;
  int prob;
  int prob_num;

  printf ( "\n" );
  printf ( "TEST02\n" );
  printf ( "  P00_DATA_NUM returns N, the number of data points.\n" );
  printf ( "  P00_DIM_NUM returns M, the dimension of data.\n" );
  printf ( "  P00_DATA returns the actual (MxN) data.\n" );

  prob_num = p00_prob_num ( );

  for ( prob = 1; prob <= prob_num; prob++ )
  {
    printf ( "\n" );
    printf ( "  Problem  %d\n", prob );

    data_num = p00_data_num ( prob );
    printf ( "  DATA_NUM %d\n", data_num );
    dim_num = p00_dim_num ( prob );
    printf ( "  DIM_NUM  %d\n", dim_num );

    p = p00_data ( prob, dim_num, data_num );

    r8mat_transpose_print ( dim_num, data_num, p, "  Data array:" );

    free ( p );
  }

  return;
}
void test171 ( )

/******************************************************************************/
/*
  Purpose:

    TEST171 tests QUAD_AREA_2D and QUAD_AREA2_2D;

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    09 May 2010

  Author:

    John Burkardt
*/
{
# define DIM_NUM 2

  double area;
  double quad[DIM_NUM*4] = {
    0.0, 0.0,
    1.0, 0.0,
    1.0, 1.0,
    0.0, 1.0 };

  printf ( "\n" );
  printf ( "TEST171\n" );
  printf ( "  For a quadrilateral in 2D:\n" );
  printf ( "  QUAD_AREA_2D finds the area;\n" );
  printf ( "  QUAD_AREA2_2D finds the area;\n" );

  r8mat_transpose_print ( DIM_NUM, 4, quad, "  The vertices:" );

  area = quad_area_2d ( quad );

  printf ( "\n" );
  printf ( "  QUAD_AREA_2D area is  %f\n", area );

  area = quad_area2_2d ( quad );

  printf ( "  QUAD_AREA2_2D area is %f\n", area );

  return;
# undef DIM_NUM
}
void test0478 ( )

/******************************************************************************/
/*
  Purpose:

    TEST0478 tests PARALLELOGRAM_AREA_3D.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    09 May 2010

  Author:

    John Burkardt
*/
{
  double area;
  double p[3*4] = {
    1.0,       2.0,       3.0, 
    2.4142137, 3.4142137, 3.0, 
    1.7071068, 2.7071068, 4.0, 
    0.2928931, 0.2928931, 4.0 };

  printf ( "\n" );
  printf ( "TEST0478\n" );
  printf ( "  PARALLELOGRAM_AREA_3D finds the area of a\n" );
  printf ( "  parallelogram in 3D.\n" );

  r8mat_transpose_print ( 3, 4, p, "  Vertices:" );

  area = parallelogram_area_3d ( p );

  printf ( "\n" );
  printf ( "  AREA = %f\n", area );

  return;
}
void test0477 ( )

/******************************************************************************/
/*
  Purpose:

    TEST0477 tests PARALLELOGRAM_AREA_2D.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    09 May 2010

  Author:

    John Burkardt
*/
{
  double area;
  double p[2*4] = {
    2.0, 7.0, 
    5.0, 7.0, 
    6.0, 9.0, 
    3.0, 9.0 };

  printf ( "\n" );
  printf ( "TEST0477\n" );
  printf ( "  PARALLELOGRAM_AREA_2D finds the area of a\n" );
  printf ( "  parallelogram in 2D.\n" );

  r8mat_transpose_print ( 2, 4, p, "  Vertices:" );

  area = parallelogram_area_2d ( p );

  printf ( "\n" );
  printf ( "  AREA = %f\n", area );

  return;
}
void test02 ( )

/******************************************************************************/
/*
  Purpose:

    TEST02 examines the sample points in the pyramid

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    14 April 2014

  Author:

    John Burkardt
*/
{
  int m = 3;
  int n = 20;
  int seed;
  double *x;

  printf ( "\n" );
  printf ( "TEST02\n" );
  printf ( "  Print sample points in the unit pyramid in 3D.\n" );
  seed = 123456789;
  x = pyramid01_sample ( n, &seed );
  r8mat_transpose_print ( 3, n, x, "  Unit pyramid points" );

  free ( x );

  return;
}
void test01 ( int prob )

/******************************************************************************/
/*
  Purpose:

    TEST01 tests CHEBYSHEV_VALUE_1D.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    27 September 2012

  Author:

    John Burkardt
*/
{
  int i;
  double int_error;
  int nd;
  int ni;
  double *xd;
  double *xi;
  double *xy;
  double *yd;
  double *yi;

  printf ( "\n" );
  printf ( "CHEBYSHEV_INTERP_1D_TEST01:\n" );
  printf ( "  Interpolate data from TEST_INTERP problem #%d\n", prob );

  nd = p00_data_num ( prob );
  printf ( "  Number of data points = %d\n", nd );

  xy = p00_data ( prob, 2, nd );
  
  r8mat_transpose_print ( 2, nd, xy, "  Data array:" );

  xd = ( double * ) malloc ( nd * sizeof ( double ) );
  yd = ( double * ) malloc ( nd * sizeof ( double ) );
  
  for ( i = 0; i < nd; i++ )
  {
    xd[i] = xy[0+i*2];
    yd[i] = xy[1+i*2];
  }
/*
  #1:  Does interpolant match function at interpolation points?
*/
  ni = nd;

  xi = ( double * ) malloc ( ni * sizeof ( double ) );

  for ( i = 0; i < ni; i++ )
  {
    xi[i] = xd[i];
  }
  yi = chebyshev_interp_1d ( nd, xd, yd, ni, xi );

  int_error = r8vec_norm_affine ( ni, yi, yd ) / ( double ) ( ni );

  printf ( "\n" );
  printf ( "  L2 interpolation error averaged per interpolant node = %g\n", int_error );

  free ( xd );
  free ( xi );
  free ( xy );
  free ( yd );
  free ( yi );

  return;
}
void test1712 ( )

/******************************************************************************/
/*
  Purpose:

    TEST1712 tests QUAD_AREA_3D;

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    09 May 2010

  Author:

    John Burkardt
*/
{
  double area;
  double area1;
  double area2;
  int i;
  int j;
  double q[3*4] = {
    2.0, 2.0, 0.0, 
    0.0, 0.0, 0.0, 
    1.0, 1.0, 1.0, 
    3.0, 3.0, 1.0 };
  double t[3*3];

  printf ( "\n" );
  printf ( "TEST1712\n" );
  printf ( "  For a quadrilateral in 3D:\n" );
  printf ( "  QUAD_AREA_3D finds the area.\n" );

  r8mat_transpose_print ( 3, 4, q, "  The vertices:");

  area = quad_area_3d ( q );

  printf ( "\n" );
  printf ( "  QUAD_AREA_3D area is     %f\n", area );

  for ( j = 0; j < 3; j++ )
  {
    for ( i = 0; i < 3; i++ )
    {
      t[i+j*3] = q[i+j*3];
    }
  }
  area1 = triangle_area_3d ( t );
  for ( j = 0; j < 2; j++ )
  {
    for ( i = 0; i < 3; i++ )
    {
      t[i+j*3] = q[i+(j+2)*3];
    }
  }
  for ( i = 0; i < 3; i++ )
  {
    t[i+2*3] = q[i+0*3];
  }
  area2 = triangle_area_3d ( t );
  printf ( "  Sum of TRIANGLE_AREA_3D: %f\n", area1 + area2 );

  return;
}
void test2101 ( )

/******************************************************************************/
/*
  Purpose:

    TEST2101 tests TRIANGLE_CIRCUMCENTER_2D and others.

  Discussion:

    The functions tested include
    * TRIANGLE_CIRCUMCENTER_2D;
    * TRIANGLE_CIRCUMCENTER_2D_2;
    * TRIANGLE_CIRCUMCENTER.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    28 October 2010

  Author:

    John Burkardt
*/
{
# define M 2
# define TEST_NUM 4

  int i;
  int j;
  int m = M;
  double *pc;
  double t[M*3];
  double t_test[M*3*TEST_NUM] = {
         10.0,  5.0, 
         11.0,  5.0, 
         10.0,  6.0, 
         10.0,  5.0, 
         11.0,  5.0, 
         10.5,  5.86602539, 
         10.0,  5.0, 
         11.0,  5.0, 
         10.5, 15.0, 
         10.0,  5.0, 
         11.0,  5.0, 
        20.0,   7.0 };
  int test;
  int test_num = TEST_NUM;

  printf ( "\n" );
  printf ( "TEST2101\n" );
  printf ( "  For a triangle in 2D, the circumenter can be computed by:\n" );
  printf ( "  TRIANGLE_CIRCUMCENTER_2D;\n" );
  printf ( "  TRIANGLE_CIRCUMCENTER_2D_2;\n" );
  printf ( "  TRIANGLE_CIRCUMCENTER (any dimension);\n" );

  for ( test = 0; test < test_num; test++ )
  {
    for ( j = 0; j < 3; j++ )
    {
      for ( i = 0; i < m; i++ )
      {
        t[i+j*m] = t_test[i+j*m+test*m*3];
      }
    }
    r8mat_transpose_print ( m, 3, t, "  Triangle vertices:" );

    pc = triangle_circumcenter_2d ( t );
    r8vec_print ( m, pc, "  Circumcenter by TRIANGLE_CIRCUMCENTER_2D:" );
    free ( pc );

    pc = triangle_circumcenter_2d_2 ( t );
    r8vec_print ( m, pc, "  Circumcenter by TRIANGLE_CIRCUMCENTER_2D_2:" );
    free ( pc );

    pc = triangle_circumcenter ( m, t );
    r8vec_print ( m, pc, "  Circumcenter by TRIANGLE_CIRCUMCENTER:" );
    free ( pc );
  }
  return;
# undef M
# undef TEST_NUM
}
void rbf_interp_nd_test01 ( void )

/******************************************************************************/
/*
  Purpose:

    RBF_INTERP_ND_TEST01 tests RBF_WEIGHTS and RBF_INTERP_ND with PHI1.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    01 July 2012

  Author:

    John Burkardt
*/
{
  double a;
  double app_error;
  double b;
  int debug = 0;
  double *fd;
  double *fe;
  double *fi;
  int i;
  double int_error;
  int j;
  int m = 2;
  int n1d = 5;
  int nd;
  int ni;
  double r0;
  int seed;
  double *w;
  double *x1d;
  double *xd;
  double *xi;

  printf ( "\n" );
  printf ( "RBF_INTERP_ND_TEST01:\n" );
  printf ( "  RBF_WEIGHT computes weights for RBF interpolation.\n" );
  printf ( "  RBF_INTERP_ND evaluates the RBF interpolant.\n" );
  printf ( "  Use the multiquadratic basis function PHI1(R).\n" );
  a = 0.0;
  b = 2.0;
  r0 = ( b - a ) / ( double ) ( n1d );
  printf ( "  Scale factor R0 = %g\n", r0 );

  x1d = r8vec_linspace_new ( n1d, a, b );
  nd = i4_power ( n1d, m );
  xd = ( double * ) malloc ( m * nd * sizeof ( double ) );

  for ( i = 0; i < m; i++ )
  {
    r8vec_direct_product ( i, n1d, x1d, m, nd, xd );
  }

  if ( debug )
  {
    r8mat_transpose_print ( m, nd, xd, "  The product points:" );
  }

  fd = ( double * ) malloc ( nd * sizeof ( double ) );
  for ( j = 0; j < nd; j++ )
  {
    fd[j] = xd[0+j*m] * xd[1+j*m] * exp ( - xd[0+j*m] * xd[1+j*m] );
  }
  if ( debug )
  {
    r8vec_print ( nd, fd, "  Function data:" );
  }

  w = rbf_weight ( m, nd, xd, r0, phi1, fd );
  if ( debug )
  {
    r8vec_print ( nd, w, "  Weight vector:" );
  }
/*
  #1: Interpolation test.  Does interpolant match function at interpolation points?
*/
  ni = nd;
  xi = r8mat_copy_new ( m, ni, xd );

  fi = rbf_interp_nd ( m, nd, xd, r0, phi1, w, ni, xi );

  int_error = r8vec_norm_affine ( nd, fd, fi ) / ( double ) ( nd );

  printf ( "\n" );
  printf ( "  L2 interpolation error averaged per interpolant node = %g\n", int_error );

  free ( fi );
  free ( xi );
/*
  #2: Approximation test.  Estimate the integral (f-interp(f))^2.
*/
  ni = 1000;
  seed = 123456789;

  xi = r8mat_uniform_ab_new ( m, ni, a, b, &seed );

  fi = rbf_interp_nd ( m, nd, xd, r0, phi1, w, ni, xi );

  fe = ( double * ) malloc ( ni * sizeof ( double ) );
  for ( j = 0; j < ni; j++ )
  {
    fe[j] = xi[0+j*m] * xi[1+j*m] * exp ( - xi[0+j*m] * xi[1+j*m] );
  }

  app_error = pow ( b - a, m ) * r8vec_norm_affine ( ni, fi, fe ) / ( double ) ( ni );

  printf ( "  L2 approximation error averaged per 1000 samples = %g\n", app_error );

  free ( fd );
  free ( fe );
  free ( fi );
  free ( w );
  free ( x1d );
  free ( xd );
  free ( xi );

  return;
}
void test005 ( )

/******************************************************************************/
/*
  Purpose:

    TEST005 tests DIAEDG.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    23 October 2012

  Author:

    John Burkardt
*/
{
  int node_num = 4;
  int triangle_num = 2;
  int triangle_order = 3;

  double alpha_area;
  double alpha_ave;
  double alpha_min_swapped;
  double alpha_min_unswapped;
  double node_xy[2*4];
  int seed = 123456789;
  int swap;
  int test;
  int test_num = 10;
  int triangle_node[3*2];
  int value;

  printf ( "\n" );
  printf ( "TEST005\n" );
  printf ( "  DIAEDG determines whether two triangles\n" );
  printf ( "  with a common edge need to \"swap\" diagonals.\n" );
  printf ( "  If swapping is indicated, then ALPHA_MIN should increase.\n" );
  printf ( "\n" );
  printf ( "  Swap   ALPHA_MIN   ALPHA_MIN\n" );
  printf ( "         Unswapped   Swapped\n" );
  printf ( "\n" );

  for ( test = 1; test <= test_num; test++ )
  {
/*
  Generate a random quadrilateral (1,2,3,4).
*/
    quad_convex_random ( &seed, node_xy );
/*
  Does it need swapping?
*/
    value = diaedg (
      node_xy[0+0*2], node_xy[1+0*2],
      node_xy[0+1*2], node_xy[1+1*2],
      node_xy[0+2*2], node_xy[1+2*2],
      node_xy[0+3*2], node_xy[1+3*2] );

    if ( value == +1 )
    {
      swap = 0;
    }
    else
    {
      swap = 1;
    }
/*
  Compute ALPHA_MIN unswapped.
*/
    triangle_node[0+0*3] = 1;
    triangle_node[1+0*3] = 2;
    triangle_node[2+0*3] = 3;
    triangle_node[0+1*3] = 1;
    triangle_node[1+1*3] = 3;
    triangle_node[2+1*3] = 4;

    alpha_measure ( node_num, node_xy, triangle_order, triangle_num,
      triangle_node, &alpha_min_unswapped, &alpha_ave, &alpha_area );
/*
  Compute ALPHA_MIN swapped.
*/
    triangle_node[0+0*3] = 1;
    triangle_node[1+0*3] = 2;
    triangle_node[2+0*3] = 4;
    triangle_node[0+1*3] = 2;
    triangle_node[1+1*3] = 3;
    triangle_node[2+1*3] = 4;

    alpha_measure ( node_num, node_xy, triangle_order, triangle_num,
      triangle_node, &alpha_min_swapped, &alpha_ave, &alpha_area );

    if ( 0 )
    {
      r8mat_transpose_print ( 2, node_num, node_xy, "  Quadrilateral" );
    }

    printf ( "     %1d  %10g  %10g\n", 
      swap, alpha_min_unswapped, alpha_min_swapped );
  }

  return;
}
void test06 ( )

/******************************************************************************/
/*
  Purpose:

    TEST06 tests TRIANGLE_CIRCUMCENTER_2D;

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    23 October 2012

  Author:

    John Burkardt
*/
{
# define DIM_NUM 2

  double *center;
  int i;
  int ntest = 4;
  double t[DIM_NUM*3];

  printf ( "\n" );
  printf ( "TEST06\n" );
  printf ( "  For a triangle in 2D:\n" );
  printf ( "  TRIANGLE_CIRCUMCENTER_2D computes the circumcenter.\n" );

  for ( i = 1; i <= ntest; i++ )
  {
    if ( i == 1 )
    {
      t[0+0*2] = 0.0;
      t[1+0*2] = 0.0;
      t[0+1*2] = 1.0;
      t[1+1*2] = 0.0;
      t[0+2*2] = 0.0;
      t[1+2*2] = 1.0;
    }
    else if ( i == 2 )
    {
      t[0+0*2] = 0.0;
      t[1+0*2] = 0.0;
      t[0+1*2] = 1.0;
      t[1+1*2] = 0.0;
      t[0+2*2] = 0.5;
      t[1+2*2] = sqrt ( 3.0 ) / 2.0;
    }
    else if ( i == 3 )
    {
      t[0+0*2] = 0.0;
      t[1+0*2] = 0.0;
      t[0+1*2] = 1.0;
      t[1+1*2] = 0.0;
      t[0+2*2] = 0.5;
      t[1+2*2] = 10.0;
    }
    else if ( i == 4 )
    {
      t[0+0*2] = 0.0;
      t[1+0*2] = 0.0;
      t[0+1*2] = 1.0;
      t[1+1*2] = 0.0;
      t[0+2*2] = 10.0;
      t[1+2*2] = 2.0;
    }

    r8mat_transpose_print ( DIM_NUM, 3, t, "  The triangle" );

    center = triangle_circumcenter_2d ( t );

    r8vec_print ( DIM_NUM, center, "  Circumcenter" );

    free ( center );
  }

  return;
# undef DIM_NUM
}
void test03 ( )

/******************************************************************************/
/*
  Purpose:

    TEST03 tests R82VEC_SORT_QUICK_A.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    23 October 2012

  Author:

    John Burkardt
*/
{
# define N 12
# define DIM_NUM 2

  double *a;
  double b = 0.0;
  double c = 10.0;
  int i;
  int j;
  int seed = 123456789;

  printf ( "\n" );
  printf ( "TEST03\n" );
  printf ( "  R82VEC_SORT_QUICK_A sorts a vector\n" );
  printf ( "    as part of a quick sort.\n" );
  printf ( "  Using initial random number seed = %d", seed );

  a = r8mat_uniform_01_new ( DIM_NUM, N, &seed );

  for ( j = 0; j < N; j++ )
  {
    for ( i = 0; i < DIM_NUM; i++ )
    {
      a[i+j*DIM_NUM] = 10.0 * a[i+j*DIM_NUM];
    }
  }
/*
  For better testing, give a few elements the same first component.
*/
  a[0+2*(3-1)] = a[0+2*(5-1)];
  a[0+2*(4-1)] = a[0+2*(12-1)];
/*
  Make two entries equal.
*/
  a[0+2*(7-1)] = a[0+2*(11-1)];
  a[1+2*(7-1)] = a[1+2*(11-1)];

  r8mat_transpose_print ( DIM_NUM, N, a, "  Before sorting:" );

  r82vec_sort_quick_a ( N, a );

  r8mat_transpose_print ( DIM_NUM, N, a, "  Sorted array:" );

  free ( a );

  return;
# undef N
# undef DIM_NUM
}
void test02 ( )

/******************************************************************************/
/*
  Purpose:

    TEST02 tests R82VEC_PART_QUICK_A.

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    23 October 2012

  Author:

    John Burkardt
*/
{
# define N 12
# define DIM_NUM 2

  double *a;
  int i;
  int j;
  int l;
  int r;
  int seed = 123456789;

  printf ( "\n" );
  printf ( "TEST02\n" );
  printf ( "  D2VEC_PART_QUICK_A reorders a D2 vector\n" );
  printf ( "    as part of a quick sort.\n" );
  printf ( "  Using initial random number seed = %d\n", seed );

  a = r8mat_uniform_01_new ( DIM_NUM, N, &seed );

  for ( j = 0; j < N; j++ )
  {
    for ( i = 0; i < DIM_NUM; i++ )
    {
      a[i+j*DIM_NUM] = 10.0 * a[i+j*DIM_NUM];
    }
  }

  r8mat_transpose_print ( DIM_NUM, N, a, "  Before rearrangment:" );

  r82vec_part_quick_a ( N, a, &l, &r );

  printf ( "\n" );
  printf ( "  Rearranged array\n" );
  printf ( "  Left index =  %d\n", l );
  printf ( "  Key index =   %d\n", l + 1 );
  printf ( "  Right index = %d\n", r );

  r8mat_transpose_print ( DIM_NUM, l,     a,         "  Left half:" );
  r8mat_transpose_print ( DIM_NUM, 1,     a+2*l,     "  Key:" );
  r8mat_transpose_print ( DIM_NUM, N-l-1, a+2*(l+1), "  Right half:" );

  free ( a );

  return;
# undef N
# undef DIM_NUM
}
void test01 ( )

/******************************************************************************/
/*
  Purpose:

    TEST01 tests POINTS_DELAUNAY_NAIVE_2D.

  Diagram:

   !....3&11....
   !............
   !............
   X..9.........
   !.....5......
   !...........6
   !.4.2...10...
   !.....8...12.
   V............
   !..7.........
   !......1.....
   !............
   !............
   !----V----X--

  Licensing:

    This code is distributed under the GNU LGPL license.

  Modified:

    23 October 2012

  Author:

    John Burkardt
*/
# define N 12
# define DIM_NUM 2
{
  int i;
  int ntri;
  int *tri;
  double p[DIM_NUM*N] = {
     7.0, 3.0,
     4.0,  7.0,
     5.0, 13.0,
     2.0,  7.0,
     6.0,  9.0,
    12.0, 10.0,
     3.0,  4.0,
     6.0,  6.0,
     3.0, 10.0,
     8.0,  7.0,
     5.0, 13.0,
    10.0,  6.0 };

  printf ( "\n" );
  printf ( "TEST01\n" );
  printf ( "  POINTS_DELAUNAY_NAIVE_2D computes the Delaunay\n" );
  printf ( "  triangulation of a set of points.\n" );

  r8mat_transpose_print ( DIM_NUM, N, p, "  The points:" );

  tri = points_delaunay_naive_2d ( N, p, &ntri );

  printf ( "\n" );
  printf ( "  Number of triangles is NTRI = %d\n", ntri );

  i4mat_transpose_print ( 3, ntri, tri, "  The Delaunay triangles:" );

  free ( tri );

  return;
# undef N
# undef DIM_NUM
}