octave-maintainers
[Top][All Lists]
Advanced

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

OOP: update to documentation


From: Robert T. Short
Subject: OOP: update to documentation
Date: Sun, 24 May 2009 10:26:22 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.21) Gecko/20090402 SeaMonkey/1.1.16

Not terribly complete, but at least users will have some idea the inheritance features exist.

Bob
--
Robert T. Short
PhaseLocked Systems
# HG changeset patch
# User Robert T. Short <address@hidden>
# Date 1243185787 25200
# Node ID e5fb8a804aa1e107e79e5203978a3a4bbdbda4f7
# Parent  d9ecd4bdece040f56a1d0b4a0d7df4ef45a619fc
   * examples/@FIRfilter: added FIRfilter class example.
   * doc/interpreter/oop.txi: Added inheritance documentatin

diff -r d9ecd4bdece0 -r e5fb8a804aa1 ChangeLog
--- a/ChangeLog Tue Apr 28 10:17:07 2009 -0700
+++ b/ChangeLog Sun May 24 10:23:07 2009 -0700
@@ -1,3 +1,7 @@
+2009-05-24  Robert T. Short  <address@hidden>
+
+       * examples/@FIRfilter: added FIRfilter class example.
+
 2009-05-22  Marco Atzeri  <address@hidden>
 
         * src/sysdep.cc: Removed CYGWIN_init 
diff -r d9ecd4bdece0 -r e5fb8a804aa1 doc/ChangeLog
--- a/doc/ChangeLog     Tue Apr 28 10:17:07 2009 -0700
+++ b/doc/ChangeLog     Sun May 24 10:23:07 2009 -0700
@@ -1,3 +1,7 @@
+2009-05-24  Robert T. Short  <address@hidden>
+
+       * interpreter/oop.txi: Added inheritance documentatin
+
 2009-05-21  Rik  <address@hidden>
 
        * interpreter/Makefile.in, texmf.cnf: Change texi2pdf call to include 
local
diff -r d9ecd4bdece0 -r e5fb8a804aa1 doc/interpreter/oop.txi
--- a/doc/interpreter/oop.txi   Tue Apr 28 10:17:07 2009 -0700
+++ b/doc/interpreter/oop.txi   Sun May 24 10:23:07 2009 -0700
@@ -51,6 +51,7 @@
 * Manipulating Classes::
 * Indexing Objects::
 * Overloading Objects::
+* Inheritance and Aggregation::
 @end menu
 
 @node Creating a Class
@@ -151,7 +152,7 @@
 @DOCSTRING(methods)
 
 @noindent
-To enquiry whether a particular method is available to a user class, the
+To inquire whether a particular method is available to a user class, the
 @code{ismethod} function can be used.
 
 @DOCSTRING(ismethod)
@@ -251,7 +252,7 @@
 @node Indexing Objects
 @section Indexing Objects
 
-Objects in can be indexed with parentheses, either like 
+Objects can be indexed with parentheses, either like 
 @address@hidden (@var{idx})} or like @address@hidden @address@hidden@}}, or 
even
 like @address@hidden (@var{idx})address@hidden  However, it is up to the user
 to decide what this indexing actually means.  In the case of our polynomial
@@ -274,7 +275,7 @@
 @DOCSTRING(subsasgn)
 
 If you wish to use the @code{end} keyword in subscripted expressions
-of an object.  Then the user needs to define the @code{end} method for 
+of an object, then the user needs to define the @code{end} method for 
 the class.
 
 @DOCSTRING(end)
@@ -476,3 +477,140 @@
 "double" class is in fact not necessary.
 
 
address@hidden Inheritance and Aggregation
address@hidden Inheritance and Aggregation
+
+Using classes to build new classes is supported by octave through the
+use of both inheritance and aggregation.
+
+Class inheritance is provided by octave using the @code{class}
+function in the class constructor.  As in the case of the polynomial
+class, the octave programmer will create a struct that contains the
+data fields required by the class, and then call the class function to
+indicate that an object is to be created from the struct.  Creating a
+child of an existing object is done by creating an object of the
+parent class and providing that object as the third argument of the
+class function.
+
+This is easily demonstrated by example.  Suppose the programmer needs
+an FIR filter, i.e. a filter with a numerator polynomial but a unity
+denominator polynomial.  In traditional octave programming, this would
+be performed as follows.
+
address@hidden
+octave:1> x = [some data vector];
+octave:2> n = [some coefficient vector];
+octave:3> y = filter (n, 1, x);
address@hidden example
+
+The equivalent class could be implemented in a class directory
+@@FIRfilter that is on the octave path.  The constructor is a file
+FIRfilter.m in the class directory.
+
address@hidden@@FIRfilter,FIRfilter.m}
+
+As before, the leading comments provide command-line documentation for
+the class constructor.  This constructor is very similar to the
+polynomial class constructor, except that we pass a polynomial object
+as the third argument to the class function, telling octave that the
+FIRfilter class will be derived from the polynomial class.  Our FIR
+filter does not have any data fields, but we must provide a struct to
+the @code{class} function.  The @code{class} function will add an
+element named polynomial to the object struct, so we simply add a
+dummy element named polynomial as the first line of the constructor.
+This dummy element will be overwritten by the class function.
+
+Note further that all our examples provide for the case in which no
+arguments are supplied.  This is important since octave will call the
+constructor with no arguments when loading ojects from save files to
+determine the inheritance structure.
+
+A class may be a child of more than one class (see the documentation
+for the @code{class} function), and inheritance may be nested.  There
+is no limitation to the number of parents or the level of nesting
+other than memory or other physical issues.
+
+As before, we need a @code{display} method.  A simple example might be
+
address@hidden@@FIRfilter,display.m}
+
+Note that we have used the polynomial field of the struct to display
+the filter coefficients.
+
+Once we have the class constructor and display method, we may create
+an object by calling the class constructor.  We may also check the
+class type and examine the underlying structure.
+
address@hidden
+octave:1> f=FIRfilter(polynomial([1 1 1]/3))
+f.polynomial = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
+octave:2> class(f)
+ans = FIRfilter
+octave:3> isa(f,"FIRfilter")
+ans =  1
+octave:4> isa(f,"polynomial")
+ans =  1
+octave:5> struct(f)
+ans = 
address@hidden
+polynomial = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
address@hidden
address@hidden example
+
+We only need to define a method to actually process data with our
+filter and our class is usable.  It is also useful to provide a means
+of changing the data stored in the class.  Since the fields in the
+underlying struct are private by default, we could provide a mechanism
+to access the fields.  The @code{subsref} method may be used for both.
+
address@hidden@@FIRfilter,subsref.m}
+
+The "()" case allows us to filter data using the polynomial provided
+to the constructor.
+
address@hidden
+octave:2> f=FIRfilter(polynomial([1 1 1]/3));
+octave:3> x=ones(5,1);
+octave:4> y=f(x)
+y =
+
+   0.33333
+   0.66667
+   1.00000
+   1.00000
+   1.00000
address@hidden example
+
+The "." case allows us to view the contents of the polynomial field.
+
address@hidden
+octave:1> f=FIRfilter(polynomial([1 1 1]/3));
+octave:2> f.polynomial
+ans = 0.333333 + 0.333333 * X + 0.333333 * X ^ 2
address@hidden example
+
+In order to change the contents of the object, we need to define a
address@hidden method.  For example, we may make the polynomial field
+publicly writeable.
+
address@hidden@@FIRfilter,subsasgn.m}
+
+So that
+
address@hidden
+octave:6> f=FIRfilter();
+octave:7> f.polynomial = polynomial([1 2 3]);
+f.polynomial = 1 + 2 * X + 3 * X ^ 2
address@hidden example
+
+
+Defining the FIRfilter class as a child of the polynomial class
+implies that and FIRfilter object may be used any place that a
+polynomial may be used.  This is not a normal use of a filter, so that
+aggregation may be a more sensible design approach.  In this case, the
+polynomial is simply a field in the class structure.  A class
+constructor for this case might be
+
address@hidden@@FIRfilter,FIRfilter_aggregation.m}
+
+For our example, the remaining class methods remain unchanged.
diff -r d9ecd4bdece0 -r e5fb8a804aa1 examples/@FIRfilter/FIRfilter.m
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/@FIRfilter/FIRfilter.m   Sun May 24 10:23:07 2009 -0700
@@ -0,0 +1,22 @@
+## -*- texinfo -*-
+## @deftypefn {Function File} {} FIRfilter ()
+## @deftypefnx {Function File} {} FIRfilter (@var{p})
+## Creates an FIR filter with polynomial @var{p} as
+## coefficient vector.
+##
+## @end deftypefn
+
+function f = FIRfilter (p)
+
+  f.polynomial = [];
+  if (nargin == 0)
+    p = @polynomial ([1]);
+  elseif (nargin == 1)
+    if (!isa (p, "polynomial"))
+      error ("FIRfilter: expecting polynomial as input argument");
+    endif
+  else
+    print_usage ();
+  endif
+  f = class (f, "FIRfilter", p);
+endfunction
diff -r d9ecd4bdece0 -r e5fb8a804aa1 examples/@FIRfilter/FIRfilter_aggregation.m
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/@FIRfilter/FIRfilter_aggregation.m       Sun May 24 10:23:07 
2009 -0700
@@ -0,0 +1,23 @@
+## -*- texinfo -*-
+## @deftypefn {Function File} {} FIRfilter ()
+## @deftypefnx {Function File} {} FIRfilter (@var{p})
+## Creates an FIR filter with polynomial @var{p} as
+## coefficient vector.
+##
+## @end deftypefn
+
+function f = FIRfilter (p)
+
+  if (nargin == 0)
+    f.polynomial = @polynomial ([1]);
+  elseif (nargin == 1)
+    if (isa (p, "polynomial"))
+      f.polynomial = p;
+    else
+      error ("FIRfilter: expecting polynomial as input argument");
+    endif
+  else
+    print_usage ();
+  endif
+  f = class (f, "FIRfilter");
+endfunction
diff -r d9ecd4bdece0 -r e5fb8a804aa1 examples/@FIRfilter/display.m
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/@FIRfilter/display.m     Sun May 24 10:23:07 2009 -0700
@@ -0,0 +1,6 @@
+function display (f)
+
+  display(f.polynomial);
+
+endfunction
+
diff -r d9ecd4bdece0 -r e5fb8a804aa1 examples/@FIRfilter/subsasgn.m
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/@FIRfilter/subsasgn.m    Sun May 24 10:23:07 2009 -0700
@@ -0,0 +1,14 @@
+function out = subsasgn (f, index, val)
+  switch (index.type)
+    case "."
+      fld = index.subs;
+      if (strcmp (fld, "polynomial"))
+        out = f;
+        out.polynomial = val;
+      else
+        error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
+      endif
+    otherwise
+      error ("FIRfilter/subsagn: Invalid index type")
+  endswitch
+endfunction
diff -r d9ecd4bdece0 -r e5fb8a804aa1 examples/@FIRfilter/subsref.m
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/@FIRfilter/subsref.m     Sun May 24 10:23:07 2009 -0700
@@ -0,0 +1,16 @@
+function out = subsref (f, x)
+  switch x.type
+    case "()"
+      n = f.polynomial;
+      out = filter(n.poly, 1, x.subs{1});
+    case "."
+      fld = x.subs;
+      if (strcmp (fld, "polynomial"))
+        out = f.polynomial;
+      else
+        error ("@FIRfilter/subsref: invalid property \"%s\"", fld);
+      endif
+    otherwise
+      error ("@FIRfilter/subsref: invalid subscript type for FIR filter");
+  endswitch
+endfunction

reply via email to

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