Mercurial > hg > octave-nkf
view liboctave/lo-specfun.cc @ 3189:bef7b73c0724
[project @ 1998-10-16 18:05:26 by jwe]
author | jwe |
---|---|
date | Fri, 16 Oct 1998 18:05:31 +0000 |
parents | 45490c020e47 |
children | 3deb1105fbc1 |
line wrap: on
line source
/* 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 (xdgamit, XDGAMIT) (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 double xgamma (double x) { double result; F77_XFCN (xdgamma, XDGAMMA, (x, result)); return result; } double xlgamma (double x) { double result; double sgngam; F77_XFCN (dlgams, DLGAMS, (x, result, sgngam)); return result; } 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; } // XXX FIXME XXX -- there is still room for improvement here... double gammainc (double x, double a) { double retval; F77_XFCN (xdgamit, XDGAMIT, (a, x, retval)); if (x == 0.0) retval = 0.0; else if (x > 0.0) retval = exp (a * log (x) + log (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: *** */