global variables in .oct-files

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

global variables in .oct-files

Stef Pillaert BK-2
Hello,

I'm trying to translate some of my octave-functions (.m-files) into C++
(.oct-files) to speed up things. I use a lot of global variables though,
otherwise I have to pass a lot of parameters to each function. Is there a
way to "see" those global variables in my C++-code? Or do I have to
include everything in the parameter-list of the function?

Thanks,

Stef Pillaert, Belgium.



Reply | Threaded
Open this post in threaded view
|

global variables in .oct-files

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

| I'm trying to translate some of my octave-functions (.m-files) into C++
| (.oct-files) to speed up things. I use a lot of global variables though,
| otherwise I have to pass a lot of parameters to each function. Is there a
| way to "see" those global variables in my C++-code?

Yes, it's possible.  Here is an example of how you can get and set
global values in .oct files:

  #include <octave/oct.h>
  #include <octave/symtab.h>

  octave_value
  get_global_value (const string& nm)
  {
    octave_value retval;

    symbol_record *sr = global_sym_tab->lookup (nm);

    if (sr)
      {
        octave_value val = sr->variable_value ();

        if (val.is_undefined ())
          error ("get_global_value: undefined symbol `%s'", nm.c_str ());
        else
          retval = val;
      }
    else
      error ("get_global_value: unknown symbol `%s'", nm.c_str ());

    return retval;
  }

  void
  set_global_value (const string& nm, const octave_value& val)
  {
    symbol_record *sr = global_sym_tab->lookup (nm, true);

    if (sr)
      sr->define (val);
    else
      panic_impossible ();
  }


  DEFUN_DLD (foo, args, ,
    "foo (global_variable_name [, val])")
  {
    octave_value_list retval;

    int nargin = args.length ();

    if (nargin == 1 || nargin == 2)
      {
        string var = args(0).string_value ();

        if (! error_state)
          {
            if (nargin == 2)
              set_global_value (var, args(1));
            else
              retval(0) = get_global_value (var);
          }
      }

    return retval;
  }

If the function defined above is called with two values, it sets the
value of the named global variable to the value of the second
argument.  If called with just one argument, it finds the value of the
named global variable:

  $ octave
  Octave, version 2.0.9 (alpha-dec-osf3.2).
  Copyright (C) 1996, 1997 John W. Eaton.
  This is free software with ABSOLUTELY NO WARRANTY.
  For details, type `warranty'.

  octave:1> x = 2
  x = 2
  octave:2> foo ("x")
  error: get_global_value: unknown symbol `x'
  error: evaluating index expression near line 2, column 1
  octave:2> global x = 2
  octave:3> foo ("x")
  ans = 2
  octave:4> foo ("y", 3)
  octave:5> function f () global y; y, end
  octave:6> f
  y = 3

Functions like this will be provided in some future version of
Octave (perhaps 2.0.10).

Thanks,

jwe


Reply | Threaded
Open this post in threaded view
|

Re: global variables in .oct-files

Stef Pillaert BK-2
At 01:02 2/10/97 -0500, you wrote:

>On 27-Sep-1997, Stef Pillaert BK <[hidden email]> wrote:
>
>| I'm trying to translate some of my octave-functions (.m-files) into C++
>| (.oct-files) to speed up things. I use a lot of global variables though,
>| otherwise I have to pass a lot of parameters to each function. Is there a
>| way to "see" those global variables in my C++-code?
>
>Yes, it's possible.  Here is an example of how you can get and set
>global values in .oct files:
>
>  #include <octave/oct.h>
>  #include <octave/symtab.h>
>
>  octave_value
>  get_global_value (const string& nm)
>  {
>    octave_value retval;
>
>    symbol_record *sr = global_sym_tab->lookup (nm);
>
>    if (sr)
>      {
> octave_value val = sr->variable_value ();
>
> if (val.is_undefined ())
>  error ("get_global_value: undefined symbol `%s'", nm.c_str ());
> else
>  retval = val;
>      }
>    else
>      error ("get_global_value: unknown symbol `%s'", nm.c_str ());
>
>    return retval;
>  }
>
>  void
>  set_global_value (const string& nm, const octave_value& val)
>  {
>    symbol_record *sr = global_sym_tab->lookup (nm, true);
>
>    if (sr)
>      sr->define (val);
>    else
>      panic_impossible ();
>  }
>
>
>  DEFUN_DLD (foo, args, ,
>    "foo (global_variable_name [, val])")
>  {
>    octave_value_list retval;
>
>    int nargin = args.length ();
>
>    if (nargin == 1 || nargin == 2)
>      {
> string var = args(0).string_value ();
>
> if (! error_state)
>  {
>    if (nargin == 2)
>      set_global_value (var, args(1));
>    else
>      retval(0) = get_global_value (var);
>  }
>      }
>
>    return retval;
>  }
>
>If the function defined above is called with two values, it sets the
>value of the named global variable to the value of the second
>argument.  If called with just one argument, it finds the value of the
>named global variable:
>

This works great, but what I want to do now is: just changing a few
elements in a large (global) variable. So I'm really looking for a
translation of what in a .m-file would be:

function f1()
global matrixa
matrixa(1,1)=10000;
end

(yes, I actually use a function as if it was a "procedure").

I tried to translate this into C++ with something like:

   octave_value val=get_global_value("matrixa");
   Matrix matrixb = val.matrix_value();
   matrixb(1,1) = 10000;      
   octave_value val2=octave_value(matrixb);
   set_global_value("matrixa",val2);

This doesn't work (octave crashes on it), and even if it would work, I
presume there is an unnecessary copy of the  global variable. I tried to
write a C++ function "change_global_value" (or should it be
"change_some_elements_in_global_value" ?), but I'm affraid my knowledge of
C++ is to limited and I get into trouble with pointers and stuff... Anyone
with a few minutes of time to help me out?
Thanks,

Stef.


Reply | Threaded
Open this post in threaded view
|

Re: global variables in .oct-files

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

| At 01:02 2/10/97 -0500, you wrote:
| >On 27-Sep-1997, Stef Pillaert BK <[hidden email]> wrote:
| >
| >| I'm trying to translate some of my octave-functions (.m-files) into C++
| >| (.oct-files) to speed up things. I use a lot of global variables though,
| >| otherwise I have to pass a lot of parameters to each function. Is there a
| >| way to "see" those global variables in my C++-code?
| >
| >Yes, it's possible.  Here is an example of how you can get and set
| >global values in .oct files:
| >
| > [...]

| This works great, but what I want to do now is: just changing a few
| elements in a large (global) variable. So I'm really looking for a
| translation of what in a .m-file would be:
|
| function f1()
| global matrixa
| matrixa(1,1)=10000;
| end
|
| (yes, I actually use a function as if it was a "procedure").
|
| I tried to translate this into C++ with something like:
|
|    octave_value val=get_global_value("matrixa");
|    Matrix matrixb = val.matrix_value();
|    matrixb(1,1) = 10000;      
|    octave_value val2=octave_value(matrixb);
|    set_global_value("matrixa",val2);
|
| This doesn't work (octave crashes on it),

It should work, but you have to remember that the C++ Matrix type uses
zero-based indexing.  So an equivalent function would be something
like this (using the definitions of get_global_value and
set_global_value as before):

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

    octave_value val = get_global_value ("a");

    if (val.is_defined ())
      {
        Matrix a = val.matrix_value ();

        // Might also want to include checks on the dimensions here...

        a(0,0) = 10000;

        set_global_value ("a", a);
      }
    else
      error ("unable to find symbol `a' in global scope!");

    return retval;
  }

  Octave, version 2.0.9 (i686-pc-linux-gnu).
  Copyright (C) 1996, 1997 John W. Eaton.
  This is free software with ABSOLUTELY NO WARRANTY.
  For details, type `warranty'.

  octave:1> a = zeros (3);
  octave:2> foo
  error: get_global_value: unknown symbol `a'
  error: unable to find symbol `a' in global scope!
  error: evaluating expression near line 2, column 1
  octave:2> global a
  octave:3> foo
  octave:4> a
  a =

    10000      0      0
        0      0      0
        0      0      0


| and even if it would work, I presume there is an unnecessary copy of
| the  global variable. I tried to write a C++ function
| "change_global_value" (or should it be
| "change_some_elements_in_global_value" ?), but I'm affraid my
| knowledge of C++ is to limited and I get into trouble with pointers
| and stuff... Anyone with a few minutes of time to help me out?

Yes, the above function creates a second copy of the matrix when the
indexed assignment operation is executed.

Unfortunately, there's currently no good way to avoid this problem.
I've added a note about it to the PROJECTS file.

Thanks,

jwe