.oct-files

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

.oct-files

Stef Pillaert BK-2
Hello,

Situation: I managed to turn one of my octave-functions ("optel")
succesfully into a working .oct file (i.e. I wrote some code in the file
optel.cc, and then  I used "mkoctfile"...). Indeed, it works a lot faster
then my old script in optel.m !

Now, I'm trying to translate another function ("kader") to an .oct-file,
but in kader I need to call optel. Is there a way to do this? My file
optel.cc looks like this (just the sum of 2 variables...):

#include <octave/oct.h>

DEFUN_DLD (optel, args, nargout,
  "optel(a,b)\n\
\n\
sum of a and b .")
{
  int nargin = args.length();
  if (nargin != 2 || nargout > 1)
    {print_usage ("optel");
    }
  Matrix a = args(0).matrix_value();
  Matrix b = args(1).matrix_value();
  Matrix c=a+b;
  return octave_value(c);
}


I tried to write kader.cc like this:

#include <octave/oct.h>

DEFUN_DLD (kader, args, nargout,
  "kader(c,d)\n\
\n\
sum of c and d (via optel).")
{ octave_value optel(octave_value a,octave_value b);
  int nargin = args.length();
  if (nargin != 2 || nargout > 1)
    {print_usage ("kader");
    }
  octave_value c = args(0);
  octave_value d = args(1);
  octave_value e = optel(c,d);
  return e;
}


But this doesn't work (I tried "mkoctfile kader.cc optel.cc")

What does work however is changing my optel.cc file into:

#include <octave/oct.h>

Matrix optel(Matrix a,Matrix b)
{
  Matrix som=a+b;
  return som;
}

and changing my kader.cc file into:

#include <octave/oct.h>

DEFUN_DLD (kader, args, nargout,
  "kader(a,b)\n\
\n\
telt a en b op (via optel).")
{ Matrix optel(Matrix a, Matrix b);
  int nargin = args.length();
  if (nargin != 2 || nargout > 1)
    {print_usage ("kader");
    }
  Matrix c = args(0).matrix_value();
  Matrix d = args(1).matrix_value();
  Matrix e = optel(c,d);
  return octave_value(e);
}

(and: "mkoctfile kader.cc optel.cc")

But, this would mean I have to use two versions for my optel-function: one
for using directly in octave, and one for using in other .oct-files.

Is there a solution?

Thanks,

Stef.

P.S. I suppose calling a function defined in a .m-file from a .oct file is
completely out of the question?
P.S. You might suggest that I just write my complete program in C++, but
then I won't be able to take advantage of all the good things octave offers
me... (besides, C++ isn't quite my cup of tea).




Reply | Threaded
Open this post in threaded view
|

.oct-files

John W. Eaton-6
On 30-Sep-1997, Stef Pillaert <[hidden email]> wrote:

| Situation: I managed to turn one of my octave-functions ("optel")
| succesfully into a working .oct file (i.e. I wrote some code in the file
| optel.cc, and then  I used "mkoctfile"...). Indeed, it works a lot faster
| then my old script in optel.m !
|
| Now, I'm trying to translate another function ("kader") to an .oct-file,
| but in kader I need to call optel. Is there a way to do this?

Yes.

| My file optel.cc looks like this (just the sum of 2 variables...):
|
| #include <octave/oct.h>
|
| DEFUN_DLD (optel, args, nargout,
|   "optel(a,b)\n\
| \n\
| sum of a and b .")
| {
|   int nargin = args.length();
|   if (nargin != 2 || nargout > 1)
|     {print_usage ("optel");
|     }
|   Matrix a = args(0).matrix_value();
|   Matrix b = args(1).matrix_value();
|   Matrix c=a+b;
|   return octave_value(c);
| }
|
| I tried to write kader.cc like this:
|
| #include <octave/oct.h>
|
| DEFUN_DLD (kader, args, nargout,
|   "kader(c,d)\n\
| \n\
| sum of c and d (via optel).")
| { octave_value optel(octave_value a,octave_value b);
|   int nargin = args.length();
|   if (nargin != 2 || nargout > 1)
|     {print_usage ("kader");
|     }
|   octave_value c = args(0);
|   octave_value d = args(1);
|   octave_value e = optel(c,d);
|   return e;
| }

The preprocessor turns the macro `DEFUN_DLD(fcn, args, nargout)' into a
function with the following signature:

  octave_value_list
  Ffcn (const octave_value_list& args, int nargout)

(note that the convention is to prepend the original name with `F').

You can call it like this:

  DEFUN_DLD (kader, args, nargout,
    "kader(c,d)\n\
  \n\
  sum of c and d (via optel).")
  {
    octave_value_list retval;

    int nargin = args.length();

    if (nargin != 2 || nargout > 1)
      print_usage ("kader");
    else
      retval = Foptel (args, 1);

    return retval;
  }

Note that this is a trivial example since the args are passed
directly from Fkader to Foptel.  Generally, you would probably have to
do something like this:

  octave_value_list tmp;

  tmp(1) = ...
  tmp(0) = ...

(The octave_value_list type automatically resizes, so I usually insert
the values in reverse order so resizing only happens once.)

| What does work however is changing my optel.cc file into:
|
| #include <octave/oct.h>
|
| Matrix optel(Matrix a,Matrix b)
| {
|   Matrix som=a+b;
|   return som;
| }

This should probably be written as

  Matrix optel (const Matrix& a, const Matrix& b) { ... }

to avoid unnecessary copies.

| and changing my kader.cc file into:
|
| #include <octave/oct.h>
|
| DEFUN_DLD (kader, args, nargout,
|   "kader(a,b)\n\
| \n\
| telt a en b op (via optel).")
| { Matrix optel(Matrix a, Matrix b);
|   int nargin = args.length();
|   if (nargin != 2 || nargout > 1)
|     {print_usage ("kader");
|     }
|   Matrix c = args(0).matrix_value();
|   Matrix d = args(1).matrix_value();
|   Matrix e = optel(c,d);
|   return octave_value(e);
| }
|
| (and: "mkoctfile kader.cc optel.cc")

You could simply call the version of optel that works with Matrix
objects from Foptel.  I typically do this when I will also need to
call the function from code that doesn't already have octave_value or
octave_value_list objects available.  It saves some overhead of
creating and extracting.

| P.S. I suppose calling a function defined in a .m-file from a .oct file is
| completely out of the question?

No, you can do it using Ffeval.  Here is an example:

  #include <octave/oct.h>

  extern octave_value_list Ffeval (const octave_value_list&, int);

  DEFUN_DLD (foo, args, ,
    "foo (N)")
  {
    octave_value_list retval;

    if (args.length () == 1)
      {
        octave_value_list tmp;

        tmp(1) = args(0);
        tmp(0) = "hilb";

        retval = Ffeval (tmp, 1);
      }
    else
      print_usage ("foo");

    return retval;
  }

I agree that this is not the prettiest interface.  There should be a
way to do this without having to create an octave_value_list object to
pass the args, like this:

  funcall ("hilb", args, nargout);

There should also be a declaration for it somewhere in the include
files that you get by including octave/oct.h.

jwe