// Copyright (C) 2017 Michele Ginesi
//
// 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 3 of the License, 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, see
// .
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#include "defun.h"
#include
DEFUN (__expint_lentz_cmplx__, args, , "Continued fraction for exponential integral function, complex case")
{
int nargin = args.length ();
if (nargin != 1)
print_usage ();
else
{
octave_value x_arg = args(0);
if (x_arg.is_single_type ())
{
const std::complex x = args(0).float_value ();
static const std::complex tiny = pow (2, -50);
static const std::complex eps = std::numeric_limits::epsilon();
std::complex f = tiny;
std::complex C = f;
std::complex D = 0;
std::complex alpha_m = 1;
std::complex beta_m = x;
std::complex Delta = 0;
int m = 1;
int maxit = 100;
while((std::abs(Delta - 1) > eps) & (m < maxit))
{
D = beta_m + alpha_m * D;
if (D == 0)
D = tiny;
C = beta_m + alpha_m / C;
if (C == 0)
C = tiny;
D = 1 / D;
Delta = C * D;
f *= Delta;
alpha_m = floor ((m + 1) / 2);
if (beta_m == x)
beta_m = 1;
else
beta_m = x;
m++;
}
if (! error_state)
return octave_value (f);
}
else
{
const std::complex x = args(0).std::double_value ();
static const std::complex tiny = pow (2, -100);
static const std::complex eps = std::numeric_limits::epsilon();
std::complex f = tiny;
std::complex C = f;
std::complex D = 0;
std::complex alpha_m = 1;
std::complex beta_m = x;
std::complex Delta = 0;
int m = 1;
int maxit = 200;
while((std::abs(Delta - 1) > eps) & (m < maxit))
{
D = beta_m + alpha_m * D;
if (D == 0)
D = tiny;
C = beta_m + alpha_m / C;
if (C == 0)
C = tiny;
D = 1 / D;
Delta = C * D;
f *= Delta;
alpha_m = floor ((m + 1) / 2);
if (beta_m == x)
beta_m = 1;
else
beta_m = x;
m++;
}
if (! error_state)
return octave_value (f);
}
}
return octave_value_list ();
}