Mercurial > octave
diff liboctave/lo-specfun.cc @ 3146:3d5aefef14e2
[project @ 1998-02-05 20:58:44 by jwe]
author | jwe |
---|---|
date | Thu, 05 Feb 1998 20:59:48 +0000 |
parents | |
children | a494f93e60ff |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/lo-specfun.cc Thu Feb 05 20:59:48 1998 +0000 @@ -0,0 +1,557 @@ +/* + +Copyright (C) 1996 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "Range.h" +#include "dColVector.h" +#include "dMatrix.h" +#include "f77-fcn.h" +#include "lo-error.h" +#include "mx-inlines.cc" + +extern "C" +{ + int F77_FCN (rjbesl, RJBESL) (const double&, const double&, + const int&, double*, int&); + + int F77_FCN (rybesl, RYBESL) (const double&, const double&, + const int&, double*, int&); + + int F77_FCN (ribesl, RIBESL) (const double&, const double&, + const int&, const int&, double*, int&); + + int F77_FCN (rkbesl, RKBESL) (const double&, const double&, + const int&, const int&, double*, int&); + + int F77_FCN (xdacosh, XDACOSH) (const double&, double&); + + int F77_FCN (xdasinh, XDASINH) (const double&, double&); + + int F77_FCN (xdatanh, XDATANH) (const double&, double&); + + int F77_FCN (xderf, XDERF) (const double&, double&); + + int F77_FCN (xderfc, XDERFC) (const double&, double&); + + int F77_FCN (xdbetai, XDBETAI) (const double&, const double&, + const double&, double&); + + int F77_FCN (xdgamma, XDGAMMA) (const double&, double&); + + int F77_FCN (xdgami, XDGAMI) (const double&, const double&, double&); + + int F77_FCN (dlgams, DLGAMS) (const double&, double&, double&); +} + +#if !defined (HAVE_ACOSH) +double +acosh (double x) +{ + double retval; + F77_XFCN (dacosh, DACOSH, (x, retval)); + return retval; +} +#endif + +#if !defined (HAVE_ASINH) +double +asinh (double x) +{ + double retval; + F77_XFCN (dasinh, DASINH, (x, retval)); + return retval; +} +#endif + +#if !defined (HAVE_ATANH) +double +atanh (double x) +{ + double retval; + F77_XFCN (datanh, DATANH, (x, retval)); + return retval; +} +#endif + +#if !defined (HAVE_ERF) +double +erf (double x) +{ + double retval; + F77_XFCN (derf, DERF, (x, retval)); + return retval; +} +#endif + +#if !defined (HAVE_ERFC) +double +erfc (double x) +{ + double retval; + F77_XFCN (derfc, DERFC, (x, retval)); + return retval; +} +#endif + +#if !defined (HAVE_GAMMA) +double +gamma (double x) +{ + double retval; + F77_XFCN (xdgamma, XDGAMMA, (x, retval)); + return retval; +} +#endif + +#if !defined (HAVE_LGAMMA) +// If the system doesn't have lgamma, assume that it doesn't have +// signgam either. + +int signgam; + +double +lgamma (double x) +{ + double retval; + double sgngam; + + F77_XFCN (dlgams, DLGAMS, (x, retval, sgngam)); + + signgam = (int) sgngam; + + return retval; +} +#endif + +int +F77_FCN (ribesl, RIBESL) (const double& x, const double& alpha, + const int& nb, double *result, int& ncalc) +{ + int retval = 0; + F77_FCN (ribesl, RIBESL) (x, alpha, nb, 1, result, ncalc); + return retval; +} + +int +F77_FCN (rkbesl, RKBESL) (const double& x, const double& alpha, + const int& nb, double *result, int& ncalc) +{ + int retval = 0; + F77_FCN (rkbesl, RKBESL) (x, alpha, nb, 1, result, ncalc); + return retval; +} + +typedef int (*fptr) (const double&, const double&, const int&, double*, int&); + +static Matrix +do_bessel (fptr f, const char *fn, double alpha, const Matrix& x) +{ + Matrix retval; + + if (alpha >= 0.0) + { + int nb = 1; + + if (alpha >= 1.0) + { + double integral; + alpha = modf (alpha, &integral); + nb = static_cast<int> (integral) + 1; + } + + Array<double> tmp (nb); + + double *ptmp = tmp.fortran_vec (); + + int x_nr = x.rows (); + int x_nc = x.cols (); + + retval.resize (x_nr, x_nc); + + int ncalc; + + for (int j = 0; j < x_nc; j++) + { + for (int i = 0; i < x_nr; i++) + { + f (x(i,j), alpha, nb, ptmp, ncalc); + + if (ncalc < 0) + { + (*current_liboctave_error_handler) + ("%s: error computing function values", fn); + + return Matrix (); + } + + retval(i,j) = tmp(nb-1); + } + } + } + else + (*current_liboctave_error_handler) + ("%s: alpha must be greater than zero", fn); + + return retval; +} + +static Matrix +do_bessel (fptr f, const char *fn, const Range& alpha_range, + const ColumnVector& x) +{ + Matrix retval; + + double alpha_base = alpha_range.base (); + + if (alpha_base >= 0.0) + { + int nb_orig = alpha_range.nelem (); + int nb = nb_orig; + int offset = 0; + + if (alpha_base >= 1.0) + { + double integral; + alpha_base = modf (alpha_base, &integral); + offset = static_cast<int> (integral); + nb += offset; + } + + Array<double> tmp (nb); + + double *ptmp = tmp.fortran_vec (); + + int x_len = x.length (); + + retval.resize (x_len, nb_orig); + + int ncalc; + + for (int i = 0; i < x_len; i++) + { + f (x(i), alpha_base, nb, ptmp, ncalc); + + if (ncalc < 0) + { + (*current_liboctave_error_handler) + ("%s: error computing function values", fn); + + return Matrix (); + } + + for (int j = 0; j < nb_orig; j++) + retval(i,j) = tmp(offset+j); + } + } + else + (*current_liboctave_error_handler) + ("%s: alpha must be greater than zero", fn); + + return retval; +} + +Matrix +besselj (double alpha, const Matrix& x) +{ + return do_bessel (F77_FCN (rjbesl, RJBESL), "besselj", alpha, x); +} + +Matrix +bessely (double alpha, const Matrix& x) +{ + return do_bessel (F77_FCN (rybesl, RYBESL), "bessely", alpha, x); +} + +Matrix +besseli (double alpha, const Matrix& x) +{ + return do_bessel (F77_FCN (ribesl, RIBESL), "besseli", alpha, x); +} + +Matrix +besselk (double alpha, const Matrix& x) +{ + return do_bessel (F77_FCN (rkbesl, RKBESL), "besselk", alpha, x); +} + +Matrix +besselj (const Range& alpha, const ColumnVector& x) +{ + return do_bessel (F77_FCN (rjbesl, RJBESL), "besselj", alpha, x); +} + +Matrix +bessely (const Range& alpha, const ColumnVector& x) +{ + return do_bessel (F77_FCN (rybesl, RYBESL), "bessely", alpha, x); +} + +Matrix +besseli (const Range& alpha, const ColumnVector& x) +{ + return do_bessel (F77_FCN (ribesl, RIBESL), "besseli", alpha, x); +} + +Matrix +besselk (const Range& alpha, const ColumnVector& x) +{ + return do_bessel (F77_FCN (rkbesl, RKBESL), "besselk", alpha, x); +} + +static void +gripe_betainc_nonconformant (int r1, int c1, int r2, int c2, int r3, + int c3) +{ + (*current_liboctave_error_handler) + ("betainc: nonconformant arguments (x is %dx%d, a is %dx%d, b is %dx%d)", + r1, c1, r2, c2, r3, c3); +} + +double +betainc (double x, double a, double b) +{ + double retval; + F77_XFCN (xdbetai, XDBETAI, (x, a, b, retval)); + return retval; +} + +Matrix +betainc (double x, double a, const Matrix& b) +{ + int nr = b.rows (); + int nc = b.cols (); + + Matrix retval (nr, nc); + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + retval(i,j) = betainc (x, a, b(i,j)); + + return retval; +} + +Matrix +betainc (double x, const Matrix& a, double b) +{ + int nr = a.rows (); + int nc = a.cols (); + + Matrix retval (nr, nc); + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + retval(i,j) = betainc (x, a(i,j), b); + + return retval; +} + +Matrix +betainc (double x, const Matrix& a, const Matrix& b) +{ + Matrix retval; + + int a_nr = a.rows (); + int a_nc = a.cols (); + + int b_nr = b.rows (); + int b_nc = b.cols (); + + if (a_nr == b_nr && a_nc == b_nc) + { + retval.resize (a_nr, a_nc); + + for (int j = 0; j < a_nc; j++) + for (int i = 0; i < a_nr; i++) + retval(i,j) = betainc (x, a(i,j), b(i,j)); + } + else + gripe_betainc_nonconformant (1, 1, a_nr, a_nc, b_nr, b_nc); + + return retval; +} + +Matrix +betainc (const Matrix& x, double a, double b) +{ + int nr = x.rows (); + int nc = x.cols (); + + Matrix retval (nr, nc); + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + retval(i,j) = betainc (x(i,j), a, b); + + return retval; +} + +Matrix +betainc (const Matrix& x, double a, const Matrix& b) +{ + Matrix retval; + + int nr = x.rows (); + int nc = x.cols (); + + int b_nr = b.rows (); + int b_nc = b.cols (); + + if (nr == b_nr && nc == b_nc) + { + retval.resize (nr, nc); + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + retval(i,j) = betainc (x(i,j), a, b(i,j)); + } + else + gripe_betainc_nonconformant (nr, nc, 1, 1, b_nr, b_nc); + + return retval; +} + +Matrix +betainc (const Matrix& x, const Matrix& a, double b) +{ + Matrix retval; + + int nr = x.rows (); + int nc = x.cols (); + + int a_nr = a.rows (); + int a_nc = a.cols (); + + if (nr == a_nr && nc == a_nc) + { + retval.resize (nr, nc); + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + retval(i,j) = betainc (x(i,j), a(i,j), b); + } + else + gripe_betainc_nonconformant (nr, nc, a_nr, a_nc, 1, 1); + + return retval; +} + +Matrix +betainc (const Matrix& x, const Matrix& a, const Matrix& b) +{ + Matrix retval; + + int nr = x.rows (); + int nc = x.cols (); + + int a_nr = a.rows (); + int a_nc = a.cols (); + + int b_nr = b.rows (); + int b_nc = b.cols (); + + if (nr == a_nr && nr == b_nr && nc == a_nc && nc == b_nc) + { + retval.resize (nr, nc); + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + retval(i,j) = betainc (x(i,j), a(i,j), b(i,j)); + } + else + gripe_betainc_nonconformant (nr, nc, a_nr, a_nc, b_nr, b_nc); + + return retval; +} + +double +gammainc (double x, double a) +{ + double retval; + F77_XFCN (xdgami, XDGAMI, (x, a, retval)); + return retval; +} + +Matrix +gammainc (double x, const Matrix& a) +{ + int nr = a.rows (); + int nc = a.cols (); + + Matrix retval (nr, nc); + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + retval(i,j) = gammainc (x, a(i,j)); + + return retval; +} + +Matrix +gammainc (const Matrix& x, double a) +{ + int nr = x.rows (); + int nc = x.cols (); + + Matrix retval (nr, nc); + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + retval(i,j) = gammainc (x(i,j), a); + + return retval; +} + +Matrix +gammainc (const Matrix& x, const Matrix& a) +{ + Matrix retval; + + int nr = x.rows (); + int nc = x.cols (); + + int a_nr = a.rows (); + int a_nc = a.cols (); + + if (nr == a_nr && nc == a_nc) + { + retval.resize (nr, nc); + + for (int j = 0; j < nc; j++) + for (int i = 0; i < nr; i++) + retval(i,j) = gammainc (x(i,j), a(i,j)); + } + else + (*current_liboctave_error_handler) + ("gammainc: nonconformant arguments (arg 1 is %dx%d, arg 2 is %dx%d)", + nr, nc, a_nr, a_nc); + + return retval; +} + +/* +;;; Local Variables: *** +;;; mode: C++ *** +;;; End: *** +*/