help-octave
[Top][All Lists]
Advanced

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

Sparse functions for octave


From: John W. Eaton
Subject: Sparse functions for octave
Date: Wed, 20 Oct 1999 04:09:29 -0500 (CDT)

On 18-Oct-1999, A+A Adler <address@hidden> wrote:

| However, I have several questions:
| 
| 1. I have a make_sparse that works fairly well, however, I
|    can't get other *.oct files to talk to it.
| 
|    For example, I'm trying to define nnz.oct
| 
|       #include "make_sparse.h"   <- my sparse Class is defined here
|       DEFUN_DLD (nnz, args, , "blah" ) {
|          octave_value_list retval;
|          string type_name = args(0).type_name();
|          if (type_name == "scalar")
|             nnz= (args(0).double_value() != 0.0);
|          } else 
|          if (type_name == "sparse") {
|             octave_sparse S= args(0).sparse_value();
|             nnz= S.nnz();
|          } else 
|             error("nnz: don't know how to nnz this type of variable");
| 
|    Compiling, I get the following error            
|    nnz.cc: no matching function for call to `octave_value::sparse_value ()

Right, you can't add a new XXX_value() method to the octave_value
class.  The reason that things like matrix_value(), complex_value(),
etc. work is that I added those methods to the octave_value() class
for convenience, and because they are frequently used built-in types.

|    I have defined a sparse_value inside my octave_sparse Class, but
|    I can't see how to get a sparse_value of an octave_value.

Oops.  It's not easy with anything before 2.1.18.  But with that, you
can use something like this (from the new make_int.cc distributed with
2.1.18):

  DEFUN_DLD (doit, args, ,
    "doit (I)")
  {
    octave_value_list retval;

    // Might be better to use
    //
    //  args(0).type_name () == octave_integer::static_type_id ()
    //
    // But there are some problems with doing that if this function is
    // in the same shared library as the one that defines the class.
    // In that case, at least some systems will create two static data
    // members for t_id.  To fix that problem, we need a different way
    // of loading multiple functions from a single shared library...

    if (args(0).type_name () == "integer")
      {
        // At this point, we know we have a handle for an octave_integer
        // object, so we can peek at the representation and extract the
        // data.

        const octave_value& rep = args(0).get_rep ();

        int my_value = ((const octave_integer&) rep) . integer_value ();

        message ("doit", "your lucky number is: %d", my_value);
      }
    else
      gripe_wrong_type_arg ("doit", args(0));

    return retval;
  }

The octave_value class is just a handle.  The member rep points to the
actual representation.  Yes, rep is declared as

  octave_value *rep;

but it really only points to a derived type.  So, once you extract a
reference to rep, you can cast it to the actual type (don't get it
wrong, or bad things will happen).

|    When you have a 1x1 matrix and take the double_value, then some
|    conversion happens, but when you take the matrix_value of a 
|    matrix, is it just a cast that happens?

No, it is just

  Matrix octave_value::matrix_value () { return rep->matrix_value (); }

If rep is really an octave_matrix object, this ends up calling the
octave_matrix::matrix_value() method.  If rep actually points to
something else, then it either calls something_else::matrix_value()
(if it is defined) or it ends up in octave_base_value::matrix_value(),
which will signal a wrong-type-arg error.

| 2. Error handling
|    Currently I'm using error("blurb") for 
| 
|    however, I see (*current_liboctave_error_handler) used
|    in the source. Should I be using that?

The error function depends on having the Octave interpreter running.
So in a DEFUN_DLD function, which can only be used from the
interpreter, it is OK to call error.  The pointer is used in the
liboctave sources, which need to be able to work outside of Octave.

FWIW, I think it is best to define classes that can be used outside of
the interpreter as much as possible, then to make the DEFUN_DLD
functions simple wrappers.

| 3. I'd like to know how the memory management works - right
|    now I'm sure I've got memory leaks, but I'll worry about
|    this after I get the functionality working.

Octave values use a fairly simple reference counting scheme to try to
avoid unnecessary copying.

jwe



---------------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.  To ensure
that development continues, see www.che.wisc.edu/octave/giftform.html
Instructions for unsubscribing: www.che.wisc.edu/octave/archive.html
---------------------------------------------------------------------



reply via email to

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