GSoC Log Entry No. 6
Chebfun Status Report No. 3
Chebfun is definitely making some progress! Many of the tests are now passing – over 50% of them in the Chebfun folder, and over 90% in some of the other folders. I’m at the point where I can run many of the examples from the Chebfun Guide and from the book Approximation Theory and Approximation Practice.
The pencils-down date of the GSoC period is August 25th. I do plan on continuing to work on the port (for the love of the game) and maintaining it as an Octave package, but I do wish to have a final product of some sort at the finish line, so hopefully 1D Chebfun exists by then!
Here are two separate issues that I found were notable enough to pop up a few times in the codebase.
Inferior classes
If you want an official understanding of what this attribute is supposed to accomplish, you can see the documentation on class precedence.
Octave does not support this attribute yet.
Here’s my take on explaining why this attribute is useful and how it works: Define an ordinary class Bar
like so
classdef Bar
properties
val = 5
end
methods
function c = minus(a, b)
disp("Bar.minus called!")
c = a.val - b.val;
end
end
end
and a class Baz
that declares Bar
inferior to it
classdef (InferiorClasses = {?Bar}) Baz
properties
val = 3
end
methods
function c = minus(a, b)
disp("Baz.minus called!")
c = b.val - a.val;
end
end
end
Well, when you use
octave> bar = Bar;
octave> baz = Baz;
octave> minus(baz, bar)
Baz.minus called!
ans = 2
naturally, this last line will call Baz.minus
, because Baz
is the first argument.
It’s essentially the same as writing baz.minus(bar)
.
With the InferiorClasses
attribute, you should expect
octave> minus(bar, baz)
Baz.minus called!
ans = -2
With the InferiorClasses
attribute, you should expect Baz.minus called!
and ans = -2
, but since this attribute is not supported, you get
octave> minus(bar, baz)
Bar.minus called!
ans = 2
One last thing, InferiorClasses doesn’t override anything related to subsref, so if you explicitly wanted to call Bar.minus
, you can still write
octave> bar.minus(baz)
ans = 2
Chebfun uses this sort of method resolution ordering in several places; here’s an example of a classdef header
classdef (InferiorClasses = {?chebtech2, ?chebtech1}) singfun < onefun
%SINGFUN Class for functions with singular endpoint behavior.
To give a bit of context, singfun
, chebtech1
and chebtech2
are supposed to be somewhat interchangeable classes that implement the actual polynomial interpolation aspect of Chebfun, and you should be able to do basic operations like addition and subtraction interchangeably.
Since singfun
overrides operations like plus
and minus
, and so does chebtech1
and chebtech2
, the InferiorClasses
attribute is used so that each class does not need to implement all of the combinatorial possibilities of operations between them.
Here’s a peculiar part of Chebfun: The chebop
class has the following header
classdef (InferiorClasses = {?double}) chebop
Except, from the documentation given
The following MATLAB classes are always inferior to classes defined using the classdef syntax and cannot be used in this list.
double, single, int64, uint64, int32, uint32, int16, uint16, int8, uint8, char, string, logical, cell, struct, and function_handle.
So it seems as if declaring ‘double’ to be an inferior class is a bit redundant, but not prohibited.
Abstract
I’ve talked about this over at , but I’ll give a brief desription of the issue here.
classdef (Abstract) Foo
then Foo is not able to be instantiated; a subclass of Foo must be created that is not also labelled abstract.
A class is abstract when it declares:
The Abstract class attribute
An abstract method
An abstract property
So what this means is that
classdef Foo
properties (Abstract)
a
end
methods (Abstract)
function retval = exampleMethod(this)
disp("This is an abstract method!");
end
end
end
the first line should be interpreted as classdef (Abstract) Foo
, even though there’s no explicit declaration of the class as abstract itelf.
But in Octave, this isn’t true; you can instantiate Foo
directly.
In Chebfun, this problem exists with several classes, such as fun
, classicfun
, chebtech
, onefun
, and some others. These are classes that are not the leafs of an inheritance chain, and so they should not be able to be instantiated directly. Not a bug that causes an incompatibility, but nonetheless not something that should be allowed to be done by the end user.