Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
628 views
in Technique[技术] by (71.8m points)

octave - Is it possible to derive a classdef class from an old-style class?

Is it possible to derive a classdef class from an old-style class?

In Octave 4.0 the ss class is defined in the old style with @ss directory. I want to derive a class with a customized __freqresp__ method in a file myss.m located in path and with the following content:

classdef myss < ss
methods
function x = solve_svd(A,b)
  [U,S,V] = svd(A);
  si = 1.0 ./ diag(S);
  si(~isfinite(si)) = 0;
  x = V' * diag(si) * U'*b;
endfunction

function H = __freqresp__ (sys, w, cellflag = false)

  if (sys.scaled == false)
    sys = prescale (sys);
  endif

  [a, b, c, d, e, tsam] = dssdata (sys);

  if (isct (sys))  # continuous system
    s = i * w;
  else             # discrete system
    s = exp (i * w * abs (tsam));
  endif

  H = arrayfun (@(x) c*solve_svd(s*E-A,b) + d, s, "uniformoutput", false);

  if (! cellflag)
    H = cat (3, H{:});
  endif

endfunction
endmethods
endclassdef

Pityingly, Octave complains about an unknown class ss even when the control package is loaded.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

(I'm answering from a MATLAB perspective here because this is what I know best, but Octave has the exact same behavior here, so it applies equally to Octave.)

The problem with @-style classes is that MATLAB doesn't know their properties until an object of the class is created. Thus, to use an old-style class as a base class, MATLAB would have to construct a base object just to learn what the class looks like, but calling the constructor with wrong inputs could lead to an error message. Or the constructor could do hours worth of work. It is not viable to build an object just to learn what it looks like.

I think this is the core reason for introducing the classdef-style classes. There are other improvements, but none as important as this one. In @-style classes inheritance is determined at the time of object creation, and one must manually create objects of the base class first, and merge those into the derived object being created.


Here's an interesting example for an @-style class behavior that makes it impossible to use it as a base class in a classdef-style class:

@foo/foo.m:

function obj = foo(x)
if x
   obj = class(struct('a','a'),'foo');
else
   obj = class(struct('b','b'),'foo');
end

Now in MATLAB we type:

>> a=foo(0)
a = 
    foo object: 1-by-1
>> b=foo(1)
Error using class
[...]
>> clear classes
>> b=foo(1)
b = 
    foo object: 1-by-1
>> a=foo(0)
Error using class
[...]

Class foo changes depending on how the first object of the class is created. Once we've created an object in one way, the other way becomes illegal.


A solution to OP's original problem:

In Octave 4.0 the ss class is defined in the old style with @ss directory. I want to derive a class with a customized __freqresp__ method [...].

Instead of deriving a new class with a customized method, think about overriding the existing method. Simply create a directory @ss, and put a file __freqresp__.m in it. Make sure that your @ss directory lives in a directory on the Octave path that comes before the toolbox directory where the original class lives.

I'm assuming that the original __freqresp__.m is an actual method, and not a function in the class' private subdirectory. If so, it's not a method and cannot be overridden (see Function Precedence in the Octave manual).

Note that you can override overloaded functions for any type, even built-in types. For example you can create a function @double/length.m to override the length function when called with a normal (double) matrix.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...