help-octave
[Top][All Lists]
Advanced

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

Re: single/double precision in C++


From: Jaroslav Hajek
Subject: Re: single/double precision in C++
Date: Mon, 9 Nov 2009 15:37:34 +0100

On Mon, Nov 9, 2009 at 2:13 PM, Peter L. <address@hidden> wrote:
> Hello everyone,
>
> I am writing Octave interfaces for a library I have developed (see LTFAT
> on sourceforge). The interface should be able to handle both real and
> complex input in both single and double precision.
>
> This leads to code like the one further down this email. The code works,
> but there is a lot of duplication, because I end up having 4 different
> cases to handle all situations. In the end, something like this is
> necessary, because I need to call 4 different C functions, but still I
> would hope that there was a more clever way of writing the function.
>
> Any suggestions would be most welcome, because I have to do it for
> around 20 different functions.
>
> Cheers,
>
> Peter.
>

Templates could help you here. Octave 3.3.50+ provides a templatized function
octave_value_extract that extracts a specified matrix type from an octave_value.
If you want to target the 3.2.x series as well (which you probably
do), you can steal these from the development sources and define them
conditionally.

Using octave_value_extract, you could write something like:
template <class MT1, class MT2>
static octave_value do_comp_dgt_fac (const octave_value_list& args,
                                                       const int a, const int M,
                                                       void
(*lib_func) (/* TODO */))
{
  const MT1 f = octave_value_extract<MT1> args(0);
  const MT2 gf = octave_value_extract<MT1> args(0);


       const int L = f.rows();
       const int W = f.columns();
       const int R = gf.rows()*gf.columns()/L;

       const int N = L/a;

       MT2 cout(M,N*W*R);

   lib_func (...);

  return cout;
}

and then call it for the 4 cases
return do_comp_dgt_fac<Matrix, ComplexMatrix> (args, a, m, dgt_fac_r);
etc

The C prototypes pose another problem as these use different complex
number type than Octave (Octave uses std::complex and assumes the
layout conforms to Fortran and C99).

A quick solution is to let these types be implied by the template, but
that is quite unsafe, as it will silently crash if you misspell a
function's name. A better solution is to provide a trait class
converting Octave's types to LTFAT's. A possibly yet better solution
is to alter ltfat.h in such a manner that it will use a user-defined
complex type if one is provided via a #define:

#include <oct.h>
#define LTFAT_USER_COMPLEX Complex
#define LTFAT_USER_SCOMPLEX FloatComplex
#include "ltfat.h" // will now use Complex and FloatComplex for the prototypes

this can be useful in general when interfacing with other software.

hth

-- 
RNDr. Jaroslav Hajek
computing expert & GNU Octave developer
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz


reply via email to

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