octave-maintainers
[Top][All Lists]
Advanced

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

[Changeset] ismethod and subsindex functions


From: David Bateman
Subject: [Changeset] ismethod and subsindex functions
Date: Fri, 26 Sep 2008 17:25:08 +0200
User-agent: Thunderbird 2.0.0.16 (X11/20080725)

In my effort to look at documenting, and testing at the same time, the new OOP fetaures, here is a patch that adds the subsindex and ismethod functions. The subsindex function allows the conversion of a class object into a valid index vector for use in indexing expressions. That is something like

a  = myclass (1:4);
b = 1:10;
c = b (a)

the conversion of a to an index of b is handled by the subsindex method of the class. Note that Mathworks, in their wisdom or lack there of, decided that subsindex should be a zero-based index where indexing everywhere else in the matlab language is ones-based!!!!! And so subsindex must return a zero-based index vector of the class double/logical.

The ismethod function is just the same function as in matlab as I implemented as it was easy enough to add.

Note that I'm seeing some strange things with this patch in the same manner as I saw previously for the thread

http://www.nabble.com/Another-OOP-issue-to19638982.html

That is

a  = myclass (1:4);
b = 1:10;
c = b (a)

works, but then an additional call to "b(a)" results in the subsindex method not being found and the default method being found instead. This seems to be a generic issue with the OOP code. However, it is also independent of this patch and so perhaps this patch should be applied in any case. I believe that with the addition of the subsindex method and the vertcat/horzcat overloading in [] that all of the operator overloading capabilities are now in place.

Regards
David

--
David Bateman                                address@hidden
Motorola Labs - Paris +33 1 69 35 48 04 (Ph) Parc Les Algorithmes, Commune de St Aubin +33 6 72 01 06 33 (Mob) 91193 Gif-Sur-Yvette FRANCE +33 1 69 35 77 01 (Fax) The information contained in this communication has been classified as: [x] General Business Information [ ] Motorola Internal Use Only [ ] Motorola Confidential Proprietary

# HG changeset patch
# User David Bateman <address@hidden>
# Date 1222442053 -7200
# Node ID e9c25f6569d71cb691388ea60a4e9710e92570e9
# Parent  3df993edc06dcab4863d97f4b7a1255c6f5417aa
Add subsindex and ismethod functions

diff --git a/scripts/ChangeLog b/scripts/ChangeLog
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,9 @@ 2008-09-25  Søren Hauberg  <address@hidden
+2008-09-26  David Bateman  <address@hidden>
+
+       * general/subsindex.m: Dummy subsindex function for help string
+       and to throw error for use outside of a class
+       * general/Makefile.in (SOURCES): Include it here.
+
 2008-09-25  Søren Hauberg  <address@hidden>
 
        * image/imread.m, image/imwrite.m: Doc fix.
diff --git a/scripts/general/Makefile.in b/scripts/general/Makefile.in
--- a/scripts/general/Makefile.in
+++ b/scripts/general/Makefile.in
@@ -45,7 +45,8 @@ SOURCES = __isequal__.m __splinen__.m ac
   nargoutchk.m nextpow2.m nthroot.m num2str.m perror.m pol2cart.m \
   polyarea.m postpad.m prepad.m quadgk.m quadl.m quadv.m randperm.m rat.m \
   rem.m repmat.m rot90.m rotdim.m runlength.m shift.m shiftdim.m sortrows.m \
-  sph2cart.m strerror.m structfun.m sub2ind.m triplequad.m trapz.m tril.m 
triu.m
+  sph2cart.m strerror.m structfun.m sub2ind.m subsindex.m triplequad.m \
+  trapz.m tril.m triu.m
 
 DISTFILES = $(addprefix $(srcdir)/, Makefile.in $(SOURCES))
 
diff --git a/scripts/general/subsindex.m b/scripts/general/subsindex.m
new file mode 100644
--- /dev/null
+++ b/scripts/general/subsindex.m
@@ -0,0 +1,64 @@
+## Copyright (C) 2008 David Bateman
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or (at
+## your option) any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} address@hidden =} subsindex (@var{a})
+## Convert an object to an index vector. When @var{a} is a class object 
+## defined with a class constructor, then @code{subsindex} is the
+## overloading method that allows the conversion of this class object to
+## a valid indexing vector. It is important to note that
+## @code{subsindex} must return a zero-based real integer vector of the
+## class "double". For example, if the class constructor
+##
+## @example
+## @group
+## function b = myclass (a)
+##  b = myclass (struct ("a", a), "myclass");
+## endfunction
+## @end group
+## @end example
+##
+## @noindent
+## then the @code{subsindex} function
+##
+## @example
+## @group
+## function idx = subsindex (a)
+##  idx = double (a.a) - 1.0;
+## endfunction
+## @end group
+## @end example
+##
+## @noindent
+## can then be used as follows
+##
+## @example
+## @group
+## a = myclass (1:4);
+## b = 1:10;
+## b(a)
+## @result{} 1  2  3  4
+## @end group
+## @end example
+##
+## @seealso{class, subsref, subsasgn}
+## @end deftypefn
+
+function idx = subsindex (a)
+  error ("subsindex: not defined for class \"%s\"", class(a));
+endfunction
diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@ 2008-09-25  David Bateman  <address@hidden
+2008-09-26  David Bateman  <address@hidden>
+
+       * ov-class.h (idx_vector index_vector (void) const): Declare new
+       maethod.
+       * ov-class.cc (idx_vector index_vector (void) const): Define new
+       method.
+       * (Fismethod): New function.
+
 2008-09-25  David Bateman  <address@hidden>
 
        * pt-mat.cc (class tm_row_const): Add any_class test
diff --git a/src/ov-class.cc b/src/ov-class.cc
--- a/src/ov-class.cc
+++ b/src/ov-class.cc
@@ -561,6 +561,38 @@ octave_class::subsasgn (const std::strin
   return retval;
 }
 
+idx_vector
+octave_class::index_vector (void) const
+{
+  idx_vector retval;
+
+  octave_value meth = symbol_table::find_method ("subsindex", class_name ());
+
+  if (meth.is_defined ())
+    {
+      octave_value_list args;
+      args(0) = octave_value (new octave_class (map, c_name));
+
+      octave_value_list tmp = feval (meth.function_value (), args, 1);
+
+      if (!error_state && tmp.length () >= 1)
+       if (tmp(0).is_object())
+         error ("subsindex function must return a valid index vector");
+       else
+         // Index vector returned by subsindex is zero based 
+         // (why this inconsistency Mathworks?), and so we must
+         // add one to the value returned as the index_vector method
+         // expects it to be one based.
+         retval = do_binary_op (octave_value::op_add, tmp (0), 
+                        octave_value (1.0)).index_vector ();
+    }
+  else
+    error ("no subsindex method defined for class %s",
+          class_name().c_str ());
+
+  return retval;
+}
+
 size_t
 octave_class::byte_size (void) const
 {
@@ -1019,6 +1051,47 @@ Return true if @var{x} is a class object
 
   if (args.length () == 1)
     retval = args(0).is_object ();
+  else
+    print_usage ();
+
+  return retval;
+}
+
+DEFUN (ismethod, args, ,
+  "-*- texinfo -*-\n\
address@hidden {Built-in Function} {} ismethod (@var{x}, @var{method})\n\
+Return true if @var{x} is a class object and the string @var{method}\n\
+is a method of this class.\n\
address@hidden deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 2)
+    {
+      octave_value arg = args(0);
+
+      std::string class_name;
+
+      if (arg.is_object ())
+       class_name = arg.class_name ();
+      else if (arg.is_string ())
+       class_name = arg.string_value ();
+      else
+       error ("ismethod: expecting object or class name as first argument");
+
+      if (! error_state)
+       {
+         std::string method = args(1).string_value ();
+
+         if (! error_state)
+           {
+             if (load_path::find_method (class_name, method) != std::string ())
+               retval = true;
+             else
+               retval = false;
+           }
+       }
+    }
   else
     print_usage ();
 
diff --git a/src/ov-class.h b/src/ov-class.h
--- a/src/ov-class.h
+++ b/src/ov-class.h
@@ -81,6 +81,8 @@ public:
   octave_value subsasgn (const std::string& type,
                         const std::list<octave_value_list>& idx,
                         const octave_value& rhs);
+
+  idx_vector index_vector (void) const;
 
   dim_vector dims (void) const { return map.dims (); }
 

reply via email to

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