expint: help with C++

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

expint: help with C++

Michele Ginesi
Dear all,

I was thinking on move the Lentz algorithm of expint on a separate .cc
file which will be called by expint.m. The problem is that I need it to
work with the complex and I'm having some troubles when compiling. I
attach the file and the log of the error.

I would be glad if someone could help me.

Best regards,

--
Michele Ginesi

__expint_lentz_cmplx__.cc (3K) Download Attachment
expint_log (27K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: expint: help with C++

Daniel Sebald
On 08/17/2017 08:11 AM, Michele wrote:

> Dear all,
>
> I was thinking on move the Lentz algorithm of expint on a separate .cc
> file which will be called by expint.m. The problem is that I need it to
> work with the complex and I'm having some troubles when compiling. I
> attach the file and the log of the error.
>
> I would be glad if someone could help me.
>
> Best regards,
>

First error:

   CXX      libinterp/operators/libinterp_liboctinterp_la-op-b-sbm.lo
../octave/libinterp/corefcn/__expint_lentz_cmplx__.cc: In function
'octave_value_list F__expint_lentz_cmplx__(const octave_value_list&, int)':
../octave/libinterp/corefcn/__expint_lentz_cmplx__.cc:48:36: error: no
matching function for call to 'abs(octave_value)'
            while((std::abs(Delta - 1) > eps) & (m < maxit))
                                     ^
../octave/libinterp/corefcn/__expint_lentz_cmplx__.cc:48:36: note:
candidates are:
In file included from /usr/include/c++/4.8/cstdlib:72:0,
                  from /usr/include/c++/4.8/ext/string_conversions.h:41,
                  from /usr/include/c++/4.8/bits/basic_string.h:2815,
                  from /usr/include/c++/4.8/string:52,
                  from ../octave/libinterp/corefcn/defun-int.h:28,
                  from ../octave/libinterp/corefcn/defun.h:32,
                  from
../octave/libinterp/corefcn/__expint_lentz_cmplx__.cc:23:
/usr/include/stdlib.h:775:12: note: int abs(int)
  extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur;
             ^
/usr/include/stdlib.h:775:12: note:   no known conversion for argument 1
from 'octave_value' to 'int'
In file included from /usr/include/c++/4.8/ext/string_conversions.h:41:0,
                  from /usr/include/c++/4.8/bits/basic_string.h:2815,
                  from /usr/include/c++/4.8/string:52,
                  from ../octave/libinterp/corefcn/defun-int.h:28,
                  from ../octave/libinterp/corefcn/defun.h:32,
                  from
../octave/libinterp/corefcn/__expint_lentz_cmplx__.cc:23:
/usr/include/c++/4.8/cstdlib:166:3: note: long int std::abs(long int)
ETC.

The compiler thinks that std::abs() function takes an int because it
doesn't understand what the the argument Delta - 1 is.  The standard
library has other input types for std::abs(), but the compiler is just
picking the 'int' input variant to complain about because it has to
choose one.  So, you must supply std::abs() with a variable type that
the compiler knows.  It looks like you are trying to use the variant
that has an input of std::complex

http://en.cppreference.com/w/cpp/numeric/complex/abs

However, even though

           std::complex<float> Delta = 0;

is std::complex, the compiler probably doesn't understand what "Delta -
1" is because there probably is not automatic promotion from 1 to
std::complex...I'm not sure.  So, perhaps you need

   Delta - complex <float> (1.0, 0.0)

or something similar (maybe complex <int> (1,0) will work, don't know,
I'll let you experiment).  You might want to define something like

std::complex<float> cmplx1 = complex <float> (1.0, 0.0);

to reduce code bulkiness, up to you.

Note there may be another issue once you solve that, i.e.,:

(std::abs(Delta - 1) > eps)

will not work because eps is declared std::complex, i.e.,

           static const std::complex<float> eps =
std::numeric_limits<float>::epsilon();

But complex numbers are not an ordered field.  The abs(complex<T>)
template returns class T, so you will be getting a float back.  Rather
than cast ::epsilon() to a complex, you can define it as a float or
simply use ::epsilon() directly.

It's hard to describe things without having a compiler/code at hand, but
that's the general idea.  The other errors in your report seem to fall
along that same line.

Dan

Reply | Threaded
Open this post in threaded view
|

Re: expint: help with C++

John W. Eaton
Administrator
On 08/17/2017 10:57 AM, Daniel J Sebald wrote:
> On 08/17/2017 08:11 AM, Michele wrote:

> However, even though
>
>            std::complex<float> Delta = 0;
>
> is std::complex, the compiler probably doesn't understand what "Delta -
> 1" is because there probably is not automatic promotion from 1 to
> std::complex...I'm not sure.  So, perhaps you need
>
>    Delta - complex <float> (1.0, 0.0)
>
> or something similar (maybe complex <int> (1,0) will work, don't know,

<complex> defines (complex<T>, T) operators, so you just need to do
something like

   Delta + 1.0f

jwe

Reply | Threaded
Open this post in threaded view
|

Re: expint: help with C++

John W. Eaton
Administrator
In reply to this post by Michele Ginesi
On 08/17/2017 09:11 AM, Michele wrote:

> I was thinking on move the Lentz algorithm of expint on a separate .cc
> file which will be called by expint.m. The problem is that I need it to
> work with the complex and I'm having some troubles when compiling. I
> attach the file and the log of the error.

Moving this to C++ is OK, but I think it should be in some functions in
liboctave, not only accessible using a DEFUN.  Then the DEFUN is a
simple wrapper for the lower-level C++ function.

If you can, make the function a template to avoid code duplication.

jwe

Reply | Threaded
Open this post in threaded view
|

Re: expint: help with C++

Michele Ginesi
On 08/17/2017 10:59 PM, John W. Eaton wrote:

> On 08/17/2017 09:11 AM, Michele wrote:
>
>> I was thinking on move the Lentz algorithm of expint on a separate
>> .cc file which will be called by expint.m. The problem is that I need
>> it to work with the complex and I'm having some troubles when
>> compiling. I attach the file and the log of the error.
>
> Moving this to C++ is OK, but I think it should be in some functions
> in liboctave, not only accessible using a DEFUN.  Then the DEFUN is a
> simple wrapper for the lower-level C++ function.
>
> If you can, make the function a template to avoid code duplication.
>
> jwe

Daniel, thank for your suggestion. It helped me a lot.

JWE, I'm not expert in C++ and I don't think I will be able to make a
template before GSoC ends. Anyway, I think that after it, with the help
of the community, we can find a way to "simplify" the code. Moreover, we
could make a template also for the Lentz algorithm of other functions
(e.g. betainc and gammainc).

--
Michele Ginesi