

// PKG_ADD: autoload ("GSL_OCTAVE_NAME", which ("gsl_sf"));
DEFUN_DLD(GSL_OCTAVE_NAME, args, nargout, "\
  -*- texinfo -*-\n\
@deftypefn {Loadable Function} {@var{z} =} GSL_OCTAVE_NAME (@var{arg1})\n\
@deftypefnx {Loadable Function} {[@var{z}, @var{err}] =} GSL_OCTAVE_NAME (@dots{})\n\
\n\
GSL_FUNC_DOCSTRING
\n\
@var{err} contains an estimate of the absolute error in the value @var{z}.\n\
\n\
This function is from the GNU Scientific Library,\n\
see @url{http://www.gnu.org/software/gsl/} for documentation.\n\
DEPRECATION_WARNING
@end deftypefn\n")
{
#ifdef HAVE_GSL_FUNC

  gsl_set_error_handler (octave_gsl_errorhandler);

  // Expected number of input arguments
  const int nb_args = 1;

  // Check the actual number of input arguments
  if (args.length() != nb_args)
    {
      print_usage ();
      return octave_value ();
    }

  // Check that all input arguments are real
  for (int i = 0; i < nb_args; i++)
    if (! ISREAL(args(i)))
      {
        error ("Input argument #%d has a complex value. "
               "A real value was expected.", i + 1);
        print_usage ();
        return octave_value ();
      }

  // Get input argument as NDArray object
  NDArray arg1 = args(0).array_value();

  // Get the dimension of the array
  dim_vector dim (arg1.dims ());
  octave_idx_type numel = dim.numel ();

  // Get a pointer to the data of the input array
  const double *arg1_data = arg1.data ();

  // Array of output values
  NDArray y (dim);

  // GSL structure that will hold each individual result
  gsl_sf_result result;

  if (nargout < 2)
    {
      // Run the calculation
      for (octave_idx_type i = 0; i < numel; i++)
        {
          GSL_FUNC_NAME (arg1_data[i], &result);
          y.xelem(i) = result.val;
        }

      return octave_value (y);
    }
  else
    {
      // Array of error estimates
      NDArray err (dim);

      // Run the calculation
      for (octave_idx_type i = 0; i < numel; i++)
        {
          GSL_FUNC_NAME (arg1_data[i], &result);
          y.xelem(i) = result.val;
          err.xelem(i) = result.err;
        }

      octave_value_list retval (2);
      retval(0) = octave_value (y);
      retval(1) = octave_value (err);
      return retval;
    }

#else // HAVE_GSL_FUNC undefined

  error ("GSL function GSL_FUNC_NAME was found missing when "
         "the gsl package for octave was built.");
  return octave_value ();

#endif // HAVE_GSL_FUNC
}
