help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Besseli Function


From: Eric Chassande-Mottin
Subject: Re: Besseli Function
Date: Mon, 8 Sep 2003 18:04:47 +0000 (GMT)


if you want I_0 only, you can try this approximation
which I have found here : momonga.t.u-tokyo.ac.jp/~ooura/
[all credits to Takuya OOURA] and which I formatted in a DLD function.

cut and copy in a file "besseli0.cc"
and compile with 

mkoctfile besseli0.cc

it would be nice if you could check the precision of this
approximation with the one made in matlab. please report
to this list. see end of this message for a first test.

note: there are other impressive approximation of special functions
here : momonga.t.u-tokyo.ac.jp/~ooura/
if you have time, it would be nice to convert all these in DLDs usable
in octave.

éric.

==== cut ==== cut ==== cut ==== cut ==== cut ==== cut ==== cut ==== cut 

// besseli0: compute Bessel I_0(x) function in double precision 

// To use this file, your version of Octave must support dynamic
// linking.  To find out if it does, type the command
//
//   x = octave_config_info; x.DEFS
//
// at the Octave prompt.  Support for dynamic linking is included if
// the output contains the string -DWITH_DYNAMIC_LINKING=1.
//
// To compile this file, type the command
//
// mkoctfile --verbose besseli0.cc
//
// at the shell prompt.  The script mkoctfile should have been
// installed along with Octave.  Running it will create a file called
// besseli0.oct that can be loaded by Octave.
//
// Enter:
//
// help besseli0
//
// at the Octave prompt to have a description of how besseli0 should be used.  
//
// Author: momonga.t.u-tokyo.ac.jp/~ooura/
//    Copyright(C) 1996 Takuya OOURA (email: address@hidden).
//    You may use, copy, modify this code for any purpose and 
//    without fee. You may distribute this ORIGINAL package.
// interface to Octave Eric Chassande-Mottin address@hidden, 8 sep 2003

//

#include <math.h>
#include <octave/config.h>

#include <iostream.h>
#include <string.h>

#include <octave/defun-dld.h>
#include <octave/error.h>
#include <octave/oct-obj.h>
#include <octave/pager.h>
#include <octave/symtab.h>
#include <octave/variables.h>

static double dbesi0(double x)
{
    int k;
    double w, t, y;
    static double a[65] = {
        8.5246820682016865877e-11, 2.5966600546497407288e-9, 
        7.9689994568640180274e-8, 1.9906710409667748239e-6, 
        4.0312469446528002532e-5, 6.4499871606224265421e-4, 
        0.0079012345761930579108, 0.071111111109207045212, 
        0.444444444444724909, 1.7777777777777532045, 
        4.0000000000000011182, 3.99999999999999998, 
        1.0000000000000000001, 
        1.1520919130377195927e-10, 2.2287613013610985225e-9, 
        8.1903951930694585113e-8, 1.9821560631611544984e-6, 
        4.0335461940910133184e-5, 6.4495330974432203401e-4, 
        0.0079013012611467520626, 0.071111038160875566622, 
        0.44444450319062699316, 1.7777777439146450067, 
        4.0000000132337935071, 3.9999999968569015366, 
        1.0000000003426703174, 
        1.5476870780515238488e-10, 1.2685004214732975355e-9, 
        9.2776861851114223267e-8, 1.9063070109379044378e-6, 
        4.0698004389917945832e-5, 6.4370447244298070713e-4, 
        0.0079044749458444976958, 0.071105052411749363882, 
        0.44445280640924755082, 1.7777694934432109713, 
        4.0000055808824003386, 3.9999977081165740932, 
        1.0000004333949319118, 
        2.0675200625006793075e-10, -6.1689554705125681442e-10, 
        1.2436765915401571654e-7, 1.5830429403520613423e-6, 
        4.2947227560776583326e-5, 6.3249861665073441312e-4, 
        0.0079454472840953930811, 0.070994327785661860575, 
        0.44467219586283000332, 1.7774588182255374745, 
        4.0003038986252717972, 3.9998233869142057195, 
        1.0000472932961288324, 
        2.7475684794982708655e-10, -3.8991472076521332023e-9, 
        1.9730170483976049388e-7, 5.9651531561967674521e-7, 
        5.1992971474748995357e-5, 5.7327338675433770752e-4, 
        0.0082293143836530412024, 0.069990934858728039037, 
        0.44726764292723985087, 1.7726685170014087784, 
        4.0062907863712704432, 3.9952750700487845355, 
        1.0016354346654179322
    };
    static double b[70] = {
        6.7852367144945531383e-8, 4.6266061382821826854e-7, 
        6.9703135812354071774e-6, 7.6637663462953234134e-5, 
        7.9113515222612691636e-4, 0.0073401204731103808981, 
        0.060677114958668837046, 0.43994941411651569622, 
        2.7420017097661750609, 14.289661921740860534, 
        59.820609640320710779, 188.78998681199150629, 
        399.8731367825601118, 427.56411572180478514, 
        1.8042097874891098754e-7, 1.2277164312044637357e-6, 
        1.8484393221474274861e-5, 2.0293995900091309208e-4, 
        0.0020918539850246207459, 0.019375315654033949297, 
        0.15985869016767185908, 1.1565260527420641724, 
        7.1896341224206072113, 37.354773811947484532, 
        155.80993164266268457, 489.5211371158540918, 
        1030.9147225169564806, 1093.5883545113746958, 
        4.8017305613187493564e-7, 3.261317843912380074e-6, 
        4.9073137508166159639e-5, 5.3806506676487583755e-4, 
        0.0055387918291051866561, 0.051223717488786549025, 
        0.42190298621367914765, 3.0463625987357355872, 
        18.895299447327733204, 97.915189029455461554, 
        407.13940115493494659, 1274.3088990480582632, 
        2670.9883037012547506, 2815.7166284662544712, 
        1.2789926338424623394e-6, 8.6718263067604918916e-6, 
        1.3041508821299929489e-4, 0.001428224737372747892, 
        0.014684070635768789378, 0.13561403190404185755, 
        1.1152592585977393953, 8.0387088559465389038, 
        49.761318895895479206, 257.2684232313529138, 
        1066.8543146269566231, 3328.3874581009636362, 
        6948.8586598121634874, 7288.4893398212481055, 
        3.409350368197032893e-6, 2.3079025203103376076e-5, 
        3.4691373283901830239e-4, 0.003794994977222908545, 
        0.038974209677945602145, 0.3594948380414878371, 
        2.9522878893539528226, 21.246564609514287056, 
        131.28727387146173141, 677.38107093296675421, 
        2802.3724744545046518, 8718.5731420798254081, 
        18141.348781638832286, 18948.925349296308859
    };
    static double c[45] = {
        2.5568678676452702768e-15, 3.0393953792305924324e-14, 
        6.3343751991094840009e-13, 1.5041298011833009649e-11, 
        4.4569436918556541414e-10, 1.746393051427167951e-8, 
        1.0059224011079852317e-6, 1.0729838945088577089e-4, 
        0.05150322693642527738, 
        5.2527963991711562216e-15, 7.202118481421005641e-15, 
        7.2561421229904797156e-13, 1.482312146673104251e-11, 
        4.4602670450376245434e-10, 1.7463600061788679671e-8, 
        1.005922609132234756e-6, 1.0729838937545111487e-4, 
        0.051503226936437300716, 
        1.3365917359358069908e-14, -1.2932643065888544835e-13, 
        1.7450199447905602915e-12, 1.0419051209056979788e-11, 
        4.58047881980598326e-10, 1.7442405450073548966e-8, 
        1.0059461453281292278e-6, 1.0729837434500161228e-4, 
        0.051503226940658446941, 
        5.3771611477352308649e-14, -1.1396193006413731702e-12, 
        1.2858641335221653409e-11, -5.9802086004570057703e-11, 
        7.3666894305929510222e-10, 1.6731837150730356448e-8, 
        1.0070831435812128922e-6, 1.0729733111203704813e-4, 
        0.051503227360726294675, 
        3.7819492084858931093e-14, -4.8600496888588034879e-13, 
        1.6898350504817224909e-12, 4.5884624327524255865e-11, 
        1.2521615963377513729e-10, 1.8959658437754727957e-8, 
        1.0020716710561353622e-6, 1.073037119856927559e-4, 
        0.05150322383300230775
    };

    w = fabs(x);
    if (w < 8.5) {
        t = w * w * 0.0625;
        k = 13 * ((int) t);
        y = (((((((((((a[k] * t + a[k + 1]) * t + 
            a[k + 2]) * t + a[k + 3]) * t + a[k + 4]) * t + 
            a[k + 5]) * t + a[k + 6]) * t + a[k + 7]) * t + 
            a[k + 8]) * t + a[k + 9]) * t + a[k + 10]) * t + 
            a[k + 11]) * t + a[k + 12];
    } else if (w < 12.5) {
        k = (int) w;
        t = w - k;
        k = 14 * (k - 8);
        y = ((((((((((((b[k] * t + b[k + 1]) * t + 
            b[k + 2]) * t + b[k + 3]) * t + b[k + 4]) * t + 
            b[k + 5]) * t + b[k + 6]) * t + b[k + 7]) * t + 
            b[k + 8]) * t + b[k + 9]) * t + b[k + 10]) * t + 
            b[k + 11]) * t + b[k + 12]) * t + b[k + 13];
    } else {
        t = 60 / w;
        k = 9 * ((int) t);
        y = ((((((((c[k] * t + c[k + 1]) * t + 
            c[k + 2]) * t + c[k + 3]) * t + c[k + 4]) * t + 
            c[k + 5]) * t + c[k + 6]) * t + c[k + 7]) * t + 
            c[k + 8]) * sqrt(t) * exp(w);
    }
    return y;
}

DEFUN_DLD (besseli0, args, ,
  "Besseli0: compute Bessel I_0(x) function in double precision.\n")
{
  octave_value_list retval;
  
  /*----------- get input parameters ----------------*/
  int nargin = args.length ();
  
  if (nargin < 1)
    {
      error("Usage: out = besseli(in)");
      return retval;
    }

  /* get the data */
  Matrix in=args(0).matrix_value();
  int c=in.columns();
  int r=in.rows();

  /* create the output data */
  Matrix out(r,c,0);
  
  for (int i=0;i<r;i++)
    for (int j=0;j<c;j++)
      out(i,j)=dbesi0((double) in(i,j));
  
  retval(0)=out;
  
  return retval;
}

==== cut ==== cut ==== cut ==== cut ==== cut ==== cut ==== cut ==== cut 

I get these results :

a=randn(5);b1=besseli(0,a),b2=besseli0(a),b1-b2

b1 =

  1.2493  1.8409  1.0170  2.4375  1.4886
  1.0099  1.1716  1.1594  1.1670  1.3552
  1.5043  1.0649  5.3553  1.0307  1.0470
  1.5625  1.0146  1.1906  1.1003  1.4390
  1.0236  1.2225  1.0923  1.2721  1.5323

b2 =

  1.2493  1.8409  1.0170  2.4375  1.4886
  1.0099  1.1716  1.1594  1.1670  1.3552
  1.5043  1.0649  5.3553  1.0307  1.0470
  1.5625  1.0146  1.1906  1.1003  1.4390
  1.0236  1.2225  1.0923  1.2721  1.5323

ans =

   -2.2204e-16    0.0000e+00    0.0000e+00    4.4409e-16   -2.2204e-16
    2.2204e-16    0.0000e+00    0.0000e+00    0.0000e+00    0.0000e+00
    0.0000e+00   -2.2204e-16    0.0000e+00    2.2204e-16    2.2204e-16
    0.0000e+00   -2.2204e-16    0.0000e+00   -4.4409e-16   -2.2204e-16
   -2.2204e-16    0.0000e+00   -2.2204e-16   -2.2204e-16   -2.2204e-16


and

a=100+randn(5);b1=besseli(0,a),b2=besseli0(a)

b1 =

 Columns 1 through 3:

          Inf +         Infi          Inf +         Infi          Inf + Infi
          Inf +         Infi          Inf +         Infi          Inf + Infi
          Inf +         Infi          Inf +         Infi          Inf + Infi
          Inf +         Infi          Inf +         Infi          Inf + Infi
          Inf +         Infi          Inf +         Infi          Inf + Infi

 Columns 4 and 5:

          Inf +         Infi          Inf +         Infi
          Inf +         Infi          Inf +         Infi
          Inf +         Infi          Inf +         Infi
          Inf +         Infi          Inf +         Infi
          Inf +         Infi          Inf +         Infi

b2 =

   1.1535e+42   7.6156e+41   7.2261e+41   1.3788e+42   4.0038e+42
   6.9361e+41   1.2384e+42   5.5145e+41   1.2641e+42   9.2007e+41
   6.4220e+42   1.2863e+41   6.8364e+41   8.9487e+41   1.6896e+42
   4.4856e+41   2.8509e+42   2.1573e+42   1.0502e+42   1.1242e+42
   3.1741e+42   5.2269e+41   4.6174e+41   9.5538e+41   2.2849e+42


> On Mon, 8 Sep 2003 13:57:37 +0200
>  "Jose Otavio Bueno" <address@hidden> wrote:
> > I'm having problems with the Besseli Functions in Octave.
> > While with 
> > Mathlab it is possible to solve the besseli functions
> > with values up to 
> > 700, with Octave the function returns a valid answer just
> > for input 
> > values below 81:
> > 
> > 
> > OCTAVE:
> > 
> > octave:1> besseli(0,1)
> > ans = 1.2661
> > octave:2> besseli(0,10)
> > ans = 2815.7
> > octave:3> besseli(0,81)
> > ans =  6.6864e+33
> > octave:4> besseli(0,82)
> > ans = Inf + Infi
> > octave:5> besseli(0,700)
> > ans = Inf + Infi
> > 
> > 
> > MATLAB:
> > 
> > >>  besseli(0,1)
> > 
> > ans =
> >     1.2661
> > 
> > >>  besseli(0,10)
> > 
> > ans =
> >     2.8157e+03
> > 
> > >>  besseli(0,81)
> > 
> > ans =
> >     6.6864e+33
> > 
> > >>  besseli(0,82)
> > 
> > ans =
> >     1.8064e+34
> > 
> > >>  besseli(0,700)
> > 
> > ans =
> >     1.5296e+302
> > 




-------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.

Octave's home on the web:  http://www.octave.org
How to fund new projects:  http://www.octave.org/funding.html
Subscription information:  http://www.octave.org/archive.html
-------------------------------------------------------------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]