From help-request at octave dot org Thu Dec 29 08:32:42 2005 Subject: Re: structures Matlab - Octave From: David Bateman To: Michael Schmid Cc: Bill Denney , help@octave.org, "John W. Eaton" Date: Thu, 29 Dec 2005 15:27:52 +0100 This is a multi-part message in MIME format. --------------060909070306090203070506 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Michael Schmid wrote: > Thanks for your answer > > is there a possible work-around ? > I don't want to stop my work at the neural network toolbox... > > by the way, I work with the Octave Version 2.9.3 and it seems to be > the same bug... > > This is not a bug... With Matlab R14sp2 I get a = struct() a = 1x1 struct array with no fields. Which is identical to octave.. The problem is rather that the subsasgn of [] doesn't delete elements of the structure array in a similar manner to the numerical matrix/array classes. octave:1> a.b = 1; a.c = 2; octave:2> a(1) ans = { b = 1 c = 2 } octave:3> a(1) = [] error: octave_base_value::map_value(): wrong type argument `matrix' error: invalid structure assignment error: assignment failed, or no method for `struct = matrix' error: evaluating assignment expression near line 9, column 6 This is a missing feature of octave in that it currently can't subsasgn [] to a structure to delete elements. This is a fairly trival addition as the underlying Cell class can (cf: a = cell(2,2); a(:,1) = [];). I've added this feature in the attached patch, which I presume John will apply in due course... Note that I get octave:1> a.b = 1; a.c = 2; octave:2> a(1) =[] a = { 0x0 struct array containing the fields: b c } octave:3> a.b octave:4> c = a.b error: value on right hand side of assignment is undefined error: evaluating assignment expression near line 4, column 3 and under matlab R14sp2 I get >> a.b = 1; a.c = 2; >> a(1)=[] a = 1x0 struct array with fields: b c >> a.b >> c = a.b ??? Too many outputs requested. Most likely cause is missing [] around left hand side that has a comma separated list expansion. Note that the size is 0-by-0 and not 1-by-0, However this is consistent with octave's handling of the [] for numeric objects.. Consider octave:5> a = 1; a(1) = [] a = [](0x0) against matlab >> a = 1; a(1) = [] a = Empty matrix: 1-by-0 Use the isempty function to test whether the structure is empty rather than the dimensions and everything should be fine.. Regards David 2005-12-14 David Bateman * oct-map.cc (maybe_delete_elements): New function. * oct-map.h (maybe_delete_elements): Declare it. * ov-struct.cc (octave_struct::subsref): Handle indexing empty structure. (octave_struct::subsasgn): If rhs is [], delete elements. (octave_struct::print_raw): Handle printing empty structure. > > Bill Denney wrote: > >> On Wed, 28 Dec 2005, Michael Schmid wrote: >> >>> Is it possible to define a structure in Octave which size(a) returns >>> [1 0 ] ? >> >> >> >> The struct command should do it for you, but in 2.1.72 (debian >> testing version) it appears to return a [1 1] struct when called as >> >> a = struct() >> >> This appears to be a bug in the struct command. >> >> Bill >> > > > > ------------------------------------------------------------- > Octave is freely available under the terms of the GNU GPL. > > Octave's home on the web: http://www.octave.org > How to fund new projects: http://www.octave.org/funding.html > Subscription information: http://www.octave.org/archive.html > ------------------------------------------------------------- > -- David Bateman David dot Bateman at motorola dot com Motorola Labs - Paris +33 1 69 35 48 04 (Ph) Parc Les Algorithmes, Commune de St Aubin +33 1 69 35 77 01 (Fax) 91193 Gif-Sur-Yvette FRANCE The information contained in this communication has been classified as: [x] General Business Information [ ] Motorola Internal Use Only [ ] Motorola Confidential Proprietary --------------060909070306090203070506 Content-Type: text/plain; name="patch.struct-20051229" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch.struct-20051229" *** ./src/oct-map.cc~ 2005-12-12 21:45:17.000000000 +0100 --- ./src/oct-map.cc 2005-12-29 14:59:12.759992084 +0100 *************** *** 210,215 **** --- 210,240 ---- } Octave_map& + Octave_map::maybe_delete_elements (const octave_value_list& idx) + { + string_vector t_keys = keys(); + octave_idx_type len = t_keys.length (); + + if (len > 0) + { + for (octave_idx_type i = 0; i < len; i++) + { + std::string k = t_keys[i]; + + map[k] = contents (k).assign (idx, Cell()); + + if (error_state) + break; + } + + if (!error_state) + dimensions = contents(t_keys[0]).dims(); + } + + return *this; + } + + Octave_map& Octave_map::assign (const octave_value_list& idx, const Octave_map& rhs) { string_vector t_keys = empty () ? rhs.keys () : equiv_keys (*this, rhs); *** ./src/oct-map.h~ 2005-12-12 21:45:17.000000000 +0100 --- ./src/oct-map.h 2005-12-29 14:22:10.288252500 +0100 *************** *** 133,138 **** --- 133,140 ---- Octave_map concat (const Octave_map& rb, const Array& ra_idx); + Octave_map& maybe_delete_elements (const octave_value_list& idx); + Octave_map& assign (const octave_value_list& idx, const Octave_map& rhs); Octave_map& assign (const octave_value_list& idx, const std::string& k, *** ./src/ov-struct.cc~ 2005-12-15 02:10:05.000000000 +0100 --- ./src/ov-struct.cc 2005-12-29 15:12:07.920223895 +0100 *************** *** 133,141 **** case '.': { ! Cell t = dotref (idx.front ()); ! retval(0) = (t.length () == 1) ? t(0) : octave_value (t, true); } break; --- 133,144 ---- case '.': { ! if (map.numel() > 1) ! { ! Cell t = dotref (idx.front ()); ! retval(0) = (t.length () == 1) ? t(0) : octave_value (t, true); ! } } break; *************** *** 307,325 **** } else { ! Octave_map rhs_map = t_rhs.map_value (); ! ! if (! error_state) { ! map.assign (idx.front (), rhs_map); if (! error_state) ! retval = octave_value (this, count + 1); else ! gripe_failed_assignment (); } else ! error ("invalid structure assignment"); } } break; --- 310,345 ---- } else { ! if (t_rhs.is_map()) { ! Octave_map rhs_map = t_rhs.map_value (); if (! error_state) ! { ! map.assign (idx.front (), rhs_map); ! ! if (! error_state) ! retval = octave_value (this, count + 1); ! else ! gripe_failed_assignment (); ! } else ! error ("invalid structure assignment"); } else ! { ! if (t_rhs.is_empty()) ! { ! map.maybe_delete_elements (idx.front()); ! ! if (! error_state) ! retval = octave_value (this, count + 1); ! else ! gripe_failed_assignment (); ! } ! else ! error ("invalid structure assignment"); ! } } } break; *************** *** 393,399 **** if (Vstruct_levels_to_print >= 0) { ! bool print_keys_only = (Vstruct_levels_to_print == 0); Vstruct_levels_to_print--; --- 413,420 ---- if (Vstruct_levels_to_print >= 0) { ! bool print_keys_only = (Vstruct_levels_to_print == 0 || ! map.numel() == 0); Vstruct_levels_to_print--; *************** *** 403,409 **** increment_indent_level (); ! octave_idx_type n = map.numel (); if (n > 1 && print_keys_only) { --- 424,430 ---- increment_indent_level (); ! octave_idx_type n = map_keys().length(); if (n > 1 && print_keys_only) { --------------060909070306090203070506-- ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------