/* * Copyright (c) 2002-2006 Samit Basu * * This program 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 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "FN.hpp" #include "Exception.hpp" #include "Array.hpp" #include "Malloc.hpp" extern "C" { double dexpei_(double*); double deone_(double*); double dei_(double*); double derfcx_(double*); double derfc_(double*); double derf_(double*); double ddaw_(double*); double dpsi_(double*); double dgamma_(double*); double dlgama_(double*); float expei_(float*); float eone_(float*); float ei_(float*); float erfcx_(float*); float erfc_(float*); float erf_(float*); float daw_(float*); float psi_(float*); float gamma_(float*); float algama_(float*); } //! //@Module EXPEI Exponential Weighted Integral Function //@@Section MATHFUNCTIONS //@@Usage //Computes the exponential weighted integral function for real arguments. The @|expei| //function takes only a single argument //@[ // y = expei(x) //@] //where @|x| is either a @|float| or @|double| array. The output //vector @|y| is the same size (and type) as @|x|. //@@Function Internals //The expei function is defined by the integral: //\[ // \mathrm{expei}(x) = - e^{-x} \int_{-x}^{\infty} \frac{e^{-t}\,dt}{t}. //\] //@@Example //Here is a plot of the @|expei| function over the range @|[-5,5]|. //@< //x = linspace(-5,5); //y = expei(x); //plot(x,y); xlabel('x'); ylabel('expei(x)'); //mprint expei1 //@> //which results in the following plot. //@figure expei1 //! ArrayVector ExpeiFunction(int nargout, const ArrayVector& arg) { if (arg.size() < 1) throw Exception("expei requires at least one argument"); Array tmp(arg[0]); if (tmp.dataClass() < FM_FLOAT) tmp.promoteType(FM_DOUBLE); if (tmp.isComplex()) throw Exception("expei does not work with complex arguments"); if (tmp.isReferenceType() || tmp.isString()) throw Exception("expei function requires numerical arguments"); if (tmp.dataClass() == FM_FLOAT) { Dimensions odims(tmp.dimensions()); int olen(odims.getElementCount()); float *sp = (float*) tmp.getDataPointer(); float *dp = (float*) Array::allocateArray(FM_FLOAT,olen); for (int i=0;i //which results in the following plot. //@figure eone1 //! ArrayVector EoneFunction(int nargout, const ArrayVector& arg) { if (arg.size() < 1) throw Exception("eone requires at least one argument"); Array tmp(arg[0]); if (tmp.dataClass() < FM_FLOAT) tmp.promoteType(FM_DOUBLE); if (tmp.isComplex()) throw Exception("eone does not work with complex arguments"); if (tmp.isReferenceType() || tmp.isString()) throw Exception("eone function requires numerical arguments"); if (tmp.dataClass() == FM_FLOAT) { Dimensions odims(tmp.dimensions()); int olen(odims.getElementCount()); float *sp = (float*) tmp.getDataPointer(); float *dp = (float*) Array::allocateArray(FM_FLOAT,olen); for (int i=0;i //which results in the following plot. //@figure ei1 //! ArrayVector EiFunction(int nargout, const ArrayVector& arg) { if (arg.size() < 1) throw Exception("ei requires at least one argument"); Array tmp(arg[0]); if (tmp.dataClass() < FM_FLOAT) tmp.promoteType(FM_DOUBLE); if (tmp.isComplex()) throw Exception("ei does not work with complex arguments"); if (tmp.isReferenceType() || tmp.isString()) throw Exception("ei function requires numerical arguments"); if (tmp.dataClass() == FM_FLOAT) { Dimensions odims(tmp.dimensions()); int olen(odims.getElementCount()); float *sp = (float*) tmp.getDataPointer(); float *dp = (float*) Array::allocateArray(FM_FLOAT,olen); for (int i=0;i //which results in the following plot. //@figure erfcx1 //! ArrayVector ErfcxFunction(int nargout, const ArrayVector& arg) { if (arg.size() < 1) throw Exception("erfcx requires at least one argument"); Array tmp(arg[0]); if (tmp.dataClass() < FM_FLOAT) tmp.promoteType(FM_DOUBLE); if (tmp.isComplex()) throw Exception("erfcx does not work with complex arguments"); if (tmp.isReferenceType() || tmp.isString()) throw Exception("erfcx function requires numerical arguments"); if (tmp.dataClass() == FM_FLOAT) { Dimensions odims(tmp.dimensions()); int olen(odims.getElementCount()); float *sp = (float*) tmp.getDataPointer(); float *dp = (float*) Array::allocateArray(FM_FLOAT,olen); for (int i=0;i //which results in the following plot. //@figure erfc1 //! ArrayVector ErfcFunction(int nargout, const ArrayVector& arg) { if (arg.size() < 1) throw Exception("erfc requires at least one argument"); Array tmp(arg[0]); if (tmp.dataClass() < FM_FLOAT) tmp.promoteType(FM_DOUBLE); if (tmp.isComplex()) throw Exception("erfc does not work with complex arguments"); if (tmp.isReferenceType() || tmp.isString()) throw Exception("erfc function requires numerical arguments"); if (tmp.dataClass() == FM_FLOAT) { Dimensions odims(tmp.dimensions()); int olen(odims.getElementCount()); float *sp = (float*) tmp.getDataPointer(); float *dp = (float*) Array::allocateArray(FM_FLOAT,olen); for (int i=0;i //which results in the following plot. //@figure erf1 //! ArrayVector ErfFunction(int nargout, const ArrayVector& arg) { if (arg.size() < 1) throw Exception("erf requires at least one argument"); Array tmp(arg[0]); if (tmp.dataClass() < FM_FLOAT) tmp.promoteType(FM_DOUBLE); if (tmp.isComplex()) throw Exception("erf does not work with complex arguments"); if (tmp.isReferenceType() || tmp.isString()) throw Exception("erf function requires numerical arguments"); if (tmp.dataClass() == FM_FLOAT) { Dimensions odims(tmp.dimensions()); int olen(odims.getElementCount()); float *sp = (float*) tmp.getDataPointer(); float *dp = (float*) Array::allocateArray(FM_FLOAT,olen); for (int i=0;i //which results in the following plot. //@figure dawson1 //! ArrayVector DawsonFunction(int nargout, const ArrayVector& arg) { if (arg.size() < 1) throw Exception("dawson requires at least one argument"); Array tmp(arg[0]); if (tmp.dataClass() < FM_FLOAT) tmp.promoteType(FM_DOUBLE); if (tmp.isComplex()) throw Exception("dawson does not work with complex arguments"); if (tmp.isReferenceType() || tmp.isString()) throw Exception("dawson function requires numerical arguments"); if (tmp.dataClass() == FM_FLOAT) { Dimensions odims(tmp.dimensions()); int olen(odims.getElementCount()); float *sp = (float*) tmp.getDataPointer(); float *dp = (float*) Array::allocateArray(FM_FLOAT,olen); for (int i=0;i //which results in the following plot. //@figure psi1 //! ArrayVector PsiFunction(int nargout, const ArrayVector& arg) { if (arg.size() < 1) throw Exception("psi requires at least one argument"); Array tmp(arg[0]); if (tmp.dataClass() < FM_FLOAT) tmp.promoteType(FM_DOUBLE); if (tmp.isComplex()) throw Exception("psi does not work with complex arguments"); if (tmp.isReferenceType() || tmp.isString()) throw Exception("psi function requires numerical arguments"); if (tmp.dataClass() == FM_FLOAT) { Dimensions odims(tmp.dimensions()); int olen(odims.getElementCount()); float *sp = (float*) tmp.getDataPointer(); float *dp = (float*) Array::allocateArray(FM_FLOAT,olen); for (int i=0;i //which results in the following plot. //@figure gamma1 //! ArrayVector GammaFunction(int nargout, const ArrayVector& arg) { if (arg.size() < 1) throw Exception("gamma requires at least one argument"); Array tmp(arg[0]); if (tmp.dataClass() < FM_FLOAT) tmp.promoteType(FM_DOUBLE); if (tmp.isComplex()) throw Exception("gamma does not work with complex arguments"); if (tmp.isReferenceType() || tmp.isString()) throw Exception("gamma function requires numerical arguments"); if (tmp.dataClass() == FM_FLOAT) { Dimensions odims(tmp.dimensions()); int olen(odims.getElementCount()); float *sp = (float*) tmp.getDataPointer(); float *dp = (float*) Array::allocateArray(FM_FLOAT,olen); for (int i=0;i //which results in the following plot. //@figure gammaln1 //! ArrayVector GammaLnFunction(int nargout, const ArrayVector& arg) { if (arg.size() < 1) throw Exception("gammaln requires at least one argument"); Array tmp(arg[0]); if (tmp.dataClass() < FM_FLOAT) tmp.promoteType(FM_DOUBLE); if (tmp.isComplex()) throw Exception("gammaln does not work with complex arguments"); if (tmp.isReferenceType() || tmp.isString()) throw Exception("gammaln function requires numerical arguments"); if (tmp.dataClass() == FM_FLOAT) { Dimensions odims(tmp.dimensions()); int olen(odims.getElementCount()); float *sp = (float*) tmp.getDataPointer(); float *dp = (float*) Array::allocateArray(FM_FLOAT,olen); for (int i=0;i