oct-files: assigning to substructures? assigning to multidimensional structures?

View: New views
3 Messages — Rating Filter:   Alert me  

oct-files: assigning to substructures? assigning to multidimensional structures?

by Olaf Till :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Taking the following structure:

octave-3.0.1:77> clear a
octave-3.0.1:78> a.b1.c1 = 1;

I thought that the following assignments:

octave-3.0.1:79> a.b2 = 1;
octave-3.0.1:80> a.b1.c2 = 1
a =
{
  b1 =
  {
    c1 =  1
    c2 =  1
  }

  b2 =  1
}

octave-3.0.1:81>

could be equivalently done with the following code (passing "a" as
first and "1" as second argument):

#include <octave/oct.h>
#include <octave/oct-map.h>

DEFUN_DLD (test_assign, args, , "test assign") {
 
  Octave_map st = args(0).map_value();
  octave_value tmp = args(1);

  st.assign("b2", tmp);

  st.contents("b1")(0).map_value().assign("c2", tmp);

  return octave_value (st);

}

but instead only the assignment to the top-level structure works:

octave-3.0.1:81> clear a
octave-3.0.1:82> a.b1.c1 = 1;
octave-3.0.1:83> a = test_assign (a, 1)
a =
{
  b1 =
  {
    c1 =  1
  }

  b2 =  1
}

octave-3.0.1:84>

What am I doing wrong?

A different question is how the equivalent of

octave-3.0.1:...> some_structure.a(2).b = 1;

can be done in an oct-file (assigning to a component of a
multidimensional structure).

Olaf
_______________________________________________
Help-octave mailing list
Help-octave@...
https://www.cae.wisc.edu/mailman/listinfo/help-octave

Re: oct-files: assigning to substructures? assigning to multidimensional structures?

by Jaroslav Hajek-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, Jun 28, 2008 at 5:10 PM, Olaf Till <olaf.till@...> wrote:

> Taking the following structure:
>
> octave-3.0.1:77> clear a
> octave-3.0.1:78> a.b1.c1 = 1;
>
> I thought that the following assignments:
>
> octave-3.0.1:79> a.b2 = 1;
> octave-3.0.1:80> a.b1.c2 = 1
> a =
> {
>  b1 =
>  {
>    c1 =  1
>    c2 =  1
>  }
>
>  b2 =  1
> }
>
> octave-3.0.1:81>
>
> could be equivalently done with the following code (passing "a" as
> first and "1" as second argument):
>
> #include <octave/oct.h>
> #include <octave/oct-map.h>
>
> DEFUN_DLD (test_assign, args, , "test assign") {
>
>  Octave_map st = args(0).map_value();
>  octave_value tmp = args(1);
>
>  st.assign("b2", tmp);
>
>  st.contents("b1")(0).map_value().assign("c2", tmp);
>
>  return octave_value (st);
>
> }
>

The problem is caused by the general Octave's philosophy of (nearly)
everything passed by value (so that you never have a problem of
dangling references), with wrappers for the actual reference-counted
objects, so that a read-only copy is as cheap as a reference.
Octave_map is no exception, and now the problem is not hard to guess:
st.contents("b1")(0).map_value() creates a *temporary copy* of the
Octave_map object inside, you then assign to this map (upon which a
clone of the original object is made),
and then it just dies away as the statement ends.

So a proper way would be (similarly to how you used the whole function):
st.contents("b1")(0) = st.contents("b1")(0).map_value().assign("c2", tmp);

To save typing (and evaluating, probably) st.contents("b1") twice, you can use:
{
  Cell& c = st.contents("b1");
  c(0) = c(0).map_value().assign("c2", tmp);
}
typicaly, only the methods or operators designed for indexed
assignment will give you a proper reference, usually you get a (cheap)
copy.

Alternatively, you can use the octave_value subsasgn method (but as
that involves constructing a std::list of octave_idx_list objects, I
doubt you would find that more convenient).







> but instead only the assignment to the top-level structure works:
>
> octave-3.0.1:81> clear a
> octave-3.0.1:82> a.b1.c1 = 1;
> octave-3.0.1:83> a = test_assign (a, 1)
> a =
> {
>  b1 =
>  {
>    c1 =  1
>  }
>
>  b2 =  1
> }
>
> octave-3.0.1:84>
>
> What am I doing wrong?
>
> A different question is how the equivalent of
>
> octave-3.0.1:...> some_structure.a(2).b = 1;
>
> can be done in an oct-file (assigning to a component of a
> multidimensional structure).
>
> Olaf
> _______________________________________________
> Help-octave mailing list
> Help-octave@...
> https://www.cae.wisc.edu/mailman/listinfo/help-octave
>



--
RNDr. Jaroslav Hajek
computing expert
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz
_______________________________________________
Help-octave mailing list
Help-octave@...
https://www.cae.wisc.edu/mailman/listinfo/help-octave

Re: oct-files: assigning to substructures? assigning to multidimensional structures?

by Olaf Till :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, Jun 28, 2008 at 06:35:54PM +0200, Jaroslav Hajek wrote:

> ...
> The problem is caused by the general Octave's philosophy of (nearly)
> everything passed by value (so that you never have a problem of
> dangling references), with wrappers for the actual reference-counted
> objects, so that a read-only copy is as cheap as a reference.
> Octave_map is no exception, and now the problem is not hard to guess:
> st.contents("b1")(0).map_value() creates a *temporary copy* of the
> Octave_map object inside, you then assign to this map (upon which a
> clone of the original object is made),
> and then it just dies away as the statement ends.
>
> So a proper way would be (similarly to how you used the whole function):
> st.contents("b1")(0) = st.contents("b1")(0).map_value().assign("c2", tmp);
>
> To save typing (and evaluating, probably) st.contents("b1") twice, you can use:
> {
>   Cell& c = st.contents("b1");
>   c(0) = c(0).map_value().assign("c2", tmp);
> }

Ah, thanks a lot. Of course, .map_value() makes a copy... Did not
think of assigning with "=" to .contents("..")(..). So .contents()()
seems to return a reference... this will probably also solve the
second problem mentioned in my post.

I'm very impressed that it's possible to get help with such a problem
within 1 h at saturday evening :-) , thanks again.

Olaf

> typicaly, only the methods or operators designed for indexed
> assignment will give you a proper reference, usually you get a (cheap)
> copy.
>
> Alternatively, you can use the octave_value subsasgn method (but as
> that involves constructing a std::list of octave_idx_list objects, I
> doubt you would find that more convenient).
>
_______________________________________________
Help-octave mailing list
Help-octave@...
https://www.cae.wisc.edu/mailman/listinfo/help-octave
LightInTheBox - Buy quality products at wholesale price