bugGNU Octave - Bugs: bug #65220, get_help_text returns docstring...

 
 

bug #65220: get_help_text returns docstring from parent methods

Submitter:  Andreas Bertsatos <pr0m1th3as>
Submitted:  Sat 27 Jan 2024 12:41:08 PM UTC
   
 
Category:  Classdef Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * stable Operating System:  * Any
Fixed Release:  9.1.0 Planned Release:  9.1.0
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Tue 06 Feb 2024 12:03:45 AM UTC, comment #58: 

Thanks for writing these tests.

John W. Eaton <jwe>
Group administrator
Mon 05 Feb 2024 10:49:18 PM UTC, comment #57: 

Whew!  It turned out to take a lot of time to fully write the tests.  I checked them in here https://hg.savannah.gnu.org/hgweb/octave/rev/2bc78bbc3fde.

Marking bug as Fixed and closing report.

Rik <rik5>
Group administrator
Mon 05 Feb 2024 04:31:13 AM UTC, comment #56: 

I pushed the following changeset:

http://hg.savannah.gnu.org/hgweb/octave/rev/ab4b7e516ff3

"Given that there is a string output from help, I can make a series of BIST tests for this bug once you have your patch applied."

Thanks.

John W. Eaton <jwe>
Group administrator
Sun 04 Feb 2024 03:59:26 PM UTC, comment #55: 

The attached patch seems to do the job.  Help for ordinary functions is restored and it passed all the help tests for classdef that I have.  Given that there is a string output from help, I can make a series of BIST tests for this bug once you have your patch applied.

Rik <rik5>
Group administrator
Sun 04 Feb 2024 04:10:09 AM UTC, comment #54: 

Please try the attached updated patch.

I see some more ways to improve and simplify comment handling in the parser and will try to work on that on the default branch.

Sorry that headed down this path so late in the release process.  As usual, the fix turned out to be more complicated than expected.  You'd think after all this time I wouldn't expect simple fixes for any problems.

If this all looks too complex or risky for the release, we could always back out the changes and move them to default.


(file #55664)

John W. Eaton <jwe>
Group administrator
Sat 03 Feb 2024 11:41:02 PM UTC, comment #53: 

Patch seems to have broken help for ordinary functions.  With patch applied:


help ls
error: help: 'ls' is not documented


For classdef, things are working as they should.  I like the new help message about the class being undocumented as shown below.


'foobar' is a class constructor from the file /home/rik/wip/Projects_Mine/octave-stable/cdef_help_bug/foobar.m

foobar is an undocumented class


Rik <rik5>
Group administrator
Sat 03 Feb 2024 10:17:46 PM UTC, comment #52: 

Thanks for testing.

Could you please try the attached change?  It makes things work better for me.  I still need to write a commit message and maybe clean up a couple of things but it would be helpful if someone could test it out a little bit before I push it.


(file #55663)

John W. Eaton <jwe>
Group administrator
Sat 03 Feb 2024 07:08:25 PM UTC, comment #51: 

Re-opening bug report.  I found an odd case where the wrong comment is used.

Minimum working example uses file foobar.m shown below and attached.


classdef foobar

  methods

    function out = foo (obj, arg1, arg2)
      out = "Called function foo()";
      % No documentation for function.
      % Try 'help foobar.foo'
      % Matlab: returns function signature "out = foo (obj, arg1, arg2)"
      % Octave: returns error
    end

  end

end


I'm working out of a build tree.  I don't think it is a problem with run-octave, but I'll document the steps exactly.


cd DEVELOPMENT_DIRECTORY
mkdir fcndir
cp foobar.m fcndir/


And then do this sequence in Octave


run-octave -f
addpath fcndir
help foobar.foo
'foobar.foo' is a function from the file /home/rik/wip/Projects_Mine/octave-stable/fcndir/foobar.m

 No documentation for function.
 Try 'help foobar.foo'
 Matlab: returns function signature "out = foo (obj, arg1, arg2)"
 Octave: returns error


Additional help for built-in functions and operators is
available in the online version of the manual.  Use the command
'doc <topic>' to search the manual index.

Help and information about Octave is also available on the WWW
at https://www.octave.org and via the help@octave.org
mailing list.


get_help_text is incorrectly locating help text that occurs after an executable statement in method foo.  But, it gets weirder.  If you ask for help about the class then the help system is reset and it no longer finds help on the method.


help foobar
error: help: 'foobar' not found
help foobar.foo
error: help: 'foobar.foo' not found



(file #55662)

Rik <rik5>
Group administrator
Sat 03 Feb 2024 06:45:00 PM UTC, comment #50: 

Verified that new code does what is expected (switching taking text from above or below the function keyword based on comment symbol).  I see another useful addition to the help system but will file a new bug report about that.

Marking bug as Fixed and closing report.

Rik <rik5>
Group administrator
Sat 03 Feb 2024 04:57:21 AM UTC, comment #49: 

I pushed the following additional changes:

http://hg.savannah.gnu.org/hgweb/octave/rev/f41297ca3e1a
http://hg.savannah.gnu.org/hgweb/octave/rev/a4dc80b3e13a

Now, Octave should choose the comment above a classdef method as the doc string if there is no comment inside the function before the first statement in the function, OR if both comments are present and a '#' is used as a comment delimiter for either of them (even if it is on just one line of a multi-line comment).

While working on this problem again, it occurred to me that it would be possible (but significantly more work) to make this choice based on whether we notice any language extensions while parsing the entire classdef file, not just by looking at the comment characters for the two comments that are candidates to be the doc string.

Marking as ready for test again.

John W. Eaton <jwe>
Group administrator
Fri 02 Feb 2024 09:25:31 PM UTC, comment #48: 

OK, I can see how the current behavior will be trouble, especially because of the choice to resolve the conflict between the comment above the function keyword and the first comment inside the function by choosing the one inside the function, EVEN WHEN the code can't be used in Matlab because of '#' comment markers.  So, I'm working on a change that will make that (Matlab-compatible) choice only when those comments only use '%' characters.  I hope to have something to check in for testing later tonight or tomorrow.  Sorry for the trouble.

John W. Eaton <jwe>
Group administrator
Fri 02 Feb 2024 08:09:24 PM UTC, comment #47: 

ok - octave does same in that case

How about?



    function somefn (obj)

      if obj
        ## Method doc inside
      end
    end


Octave gets method doc

John Donoghue <lostbard>
Group Member
Fri 02 Feb 2024 06:29:43 PM UTC, comment #46: 

In both cases it looks like it's just looking for the first commented block. if that block is empty, it shows the function definition instead.   Does this updated version for octave do that or do we require no blank lines?

Nicholas Jankowski <nrjank>
Group Member
Fri 02 Feb 2024 05:07:49 PM UTC, comment #45: 

MATLAB behaves likes this:

both files

function out = somefn(in)
  % documentation

end

function out = somefn(in)

  % documentation

end

return

>> help somefn
  documentation

>>>


but the files

function out = somefn(in)
 %

  % documentation

end

function out = somefn(in)
 %%

  %% documentation

end

return

>> help somefn
somefn is a function.
    out = somefn(in)

>>>


Apparently, an empty comment line followed by an empty line results in muting any further comment block returned as documentation

Andreas Bertsatos <pr0m1th3as>
Fri 02 Feb 2024 03:03:27 PM UTC, comment #44: 

A question for both octave and whatdoes matlab do, in the case where the inside function text is after a blank line, does maylab treat it as documentation of just a comment?

From example class below:


    function obj = foo ()

      ## should this be Ctor doc inside
    end


The changes in octave would make it the ctor doc - matlab ?


John Donoghue <lostbard>
Group Member
Thu 01 Feb 2024 09:50:23 PM UTC, comment #43: 

@jwe: I see this warning during compilation


libinterp/parse-tree/oct-parse.yy:1848.67-73: warning: unused value: $5 [-Wother]
 1848 | classdef        : classdef_beg stash_comment attr_list identifier opt...
      |                                                                   ^~~


It's only a warning, but maybe you can take a look.

Otherwise, this all looks good and passes the tests I tried with it.

Rik <rik5>
Group administrator
Thu 01 Feb 2024 09:45:55 PM UTC, comment #42: 

@Andreas: Yes, the copyright is excluded.

Rik <rik5>
Group administrator
Thu 01 Feb 2024 05:59:05 PM UTC, comment #41: 

"If both are present for the class doc or a property, the one above is preferred"

I hope this does exclude the copyright header, right? I mean that if the class documentation is below 'classdef' and there is only the copyright header above, it picks the right one and not the copyright header.


Andreas Bertsatos <pr0m1th3as>
Thu 01 Feb 2024 04:00:09 PM UTC, comment #40: 

There is currently no check on '%' vs. '#'.

"Does this mean that we have to remove any code comments right after the method definition if the help file is before the definition?"

Yes.  See comment #35.  I agree that it is potentially annoying and could cause confusion.  I've already spent a lot of time just trying to make help work for classdef.  I have to take a break from it now.  If there is a better solution, I hope someone else will submit a patch and we can discuss.

John W. Eaton <jwe>
Group administrator
Thu 01 Feb 2024 03:31:07 PM UTC, comment #39: 

Does this mean that we have to remove any code comments right after the method definition if the help file is before the definition? Does your patch differentiate between `##` and ~%~ ?

Andreas Bertsatos <pr0m1th3as>
Thu 01 Feb 2024 06:45:34 AM UTC, comment #38: 

I pushed the following changes related to this bug report:

http://hg.savannah.gnu.org/hgweb/octave/rev/d312676c51c8
http://hg.savannah.gnu.org/hgweb/octave/rev/258444f64447
http://hg.savannah.gnu.org/hgweb/octave/rev/80d3a6abfc4d
http://hg.savannah.gnu.org/hgweb/octave/rev/2faec354b977
http://hg.savannah.gnu.org/hgweb/octave/rev/82b67791bf1b

There is still a lot of room for improvement in the way we capture comments in the parser, but things work a lot better now for extracting help for functions, classdef methods, and classdef properties.

I don't think the behavior for "help fcn" changed - the first non-copyright comment block in a .m file should be used as the help text.  If there isn't one before the function definition, then the first one before the body of the function should be used.

Explaining what happens for classdef classes and methods is probably best done with an example:


## Class doc above
classdef foo
  ## Class doc inside
  methods
    ## Ctor doc above
    function obj = foo ()
      ## Ctor doc inside
    end
    ## Method doc above
    function method (obj)
      ## Method doc inside
    end
  end
  properties
    ## property doc above
    A ## property doc at eol
  end
end


  • If only one of the "above"/"inside" or "block/eol" pairs is present, that one is used
  • If neither is present, the object is undocumented
  • If both are present for the class doc or a property, the one above is preferred
  • If both are present for a ctor or method, the one inside is preferred


If there is documentation for a property, method or constructor, then "help CLASS-NAME.PROPERTY-NAME" or "help CLASS-NAME.METHOD-NAME" will display it.

If there is documentation for the class, then "help CLASS-NAME" will display it.  If there is documentation for the constructor but not the class, then "help CLASS-NAME" will show the constructor documentation.

I believe that is the current behavior with the changes I listed above.  If not, give me a test case and I'll try to fix it.

If the behavior described above is not compatible with Matlab, please also report that.

John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 11:56:04 PM UTC, comment #37: 

There are four possible combinations of comments being present before and after the function declaration

1)
## documentation or comment
function someFun
## documentation or comment
...
endfunction

2)
%% documentation or comment
function someFun
## documentation or comment
...
endfunction

3)
## documentation or comment
function someFun
%% documentation or comment
...
endfunction

4)
%% documentation or comment
function someFun
%% documentation or comment
...
endfunction

Since `#` is explicit to Octave, I would suggest that get_text_help should check both before and after the function statement and if either of the positions have comment lines starting with `#` it should return it as the help documentation. If both positions have `#` comment lines, then it should consider the above for being the documentation (let's say the Octave way). If both positions have `%` comment lines then it should do the MATLAB way and return the comments below the function statement as the documentation.

This way, code written for both MATLAB and Octave will behave similarly without the programmer or the user having to do something about it. Furthermore, code written for explicitly for Octave would still have to follow the same documentation rules that have been established so far and there is no compatibility breaking.

@jwe If you would like to take an extra step to make it even more robust for Octave code, then just in the first case, where both positions have `#` comment lines, we could check both comment blocks for the -*- texinfo -*- tag and return whichever contains it, otherwise (if none has it) prefer the comment block before the function declaration.

I think this is the best compromise between adjusting for Matlab compatible behavior and maintaining backwards compatibility with Octave code.

I am really against a configuration option solution as I think it will introduce more mess and bug reports rather than solve our current problems with correctly parsing help documentation from existing and future classdef files.

Andreas Bertsatos <pr0m1th3as>
Tue 30 Jan 2024 11:47:58 PM UTC, comment #36: 


> In this case 'help cdef_help.disp' will choose the ABOVE version.  Matlab will choose the BELOW version.


ok, the comment in the disp helps said to run "help cdef_help.meth1" not "help cdef_help.disp". thought it might have been a copy/paste error.

Nicholas Jankowski <nrjank>
Group Member
Tue 30 Jan 2024 10:01:55 PM UTC, comment #35: 

Thanks for the info about the property documentation.

"A fourth option would be to simply swap the default choice of which documentation to use when both above or below comments are present."

That is fine with me, though I can imagine it annoying some who would like to write


%% Method doc here.
function meth ()
  %% General description of function internals here.
  ... code ...
end


and not have to place at least one statement above the "% General description" comment to avoid having it used as the documentation.

John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 10:00:37 PM UTC, comment #34: 

@jwe: Matlab chooses the comment above the property over the end-of-line comment.

Rik <rik5>
Group administrator
Tue 30 Jan 2024 09:55:00 PM UTC, comment #33: 

A fourth option would be to simply swap the default choice of which documentation to use when both above or below comments are present.  In this case, Matlab users will always get what they expect, and the only change for Octave programmers is not to put a comment immediately after the "function" statement.  This is similar to the option to condition the choice based on '#' or '%', but wouldn't require syntactic changes to the code.  If a programmer is writing dual-code that is expected to run in either environment that would be nicer since the code would run in either environment.

Rik <rik5>
Group administrator
Tue 30 Jan 2024 09:54:17 PM UTC, comment #32: 

One more question that I don't think has been answered yet.  If there are comments above and on the same line as a property declaration, which one does Matlab select?


classdef foo
  properties
    %% block comment above property A
    A = 13;  %% end-of-line comment after property A
  end
end


John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 09:49:33 PM UTC, comment #31: 


> are your 'should be shown for's for the disp function right?


The word "ABOVE" and "BELOW" is different in the two help texts so that you can see which one Octave picks.  In this case 'help cdef_help.disp' will choose the ABOVE version.  Matlab will choose the BELOW version.

Rik <rik5>
Group administrator
Tue 30 Jan 2024 09:05:10 PM UTC, comment #30: 

I think it's important to preserve compatibility here.  Otherwise, just like the "for i = zeros (0, N) ... end" issue, we will just periodically get bug reports about this when Octave displays the "wrong" text for "help cls.meth" and users will get the impression that we are dumb for not making Octave to the Right Thing (and for these users, the Right Thing is always whatever it is that Matlab does).

It seems the only conflict we are talking about here is the one that occurs when there are comments just above and below the function keyword for a method in a class.

There may be more options, but I can see at least three possibilities for resolving the conflict and preserving Matlab compatibility:

  1. If the comment above the function uses "#" comment characters, do the incompatible Octave-specific behavior.  The code won't work in Matlab anyway.  If it uses '%' comment characters, do the Matlab-compatible thing and choose the comment in the function body.  That doesn't help those who want Octave to select the comment above the function keyword but happen to prefer '%' over '#'.
  2. If the comment above the function keyword starts with "-*- texinfo -*-" (or some other agreed-upon tag) then select that as the help text.  That doesn't help those who just want simple plain-text doc strings or don't know about the special tag.
  3. Use a configuration option for the parser so users can configure what they want the behavior to be.  That doesn't help those who wish to use files that were written expecting behavior different from what the configuration option specifies.


Which one is least bad?  Maybe the second one if we check the comment above the function keyword for either the "-*- texinfo -*-" tag or some other tag like "-*- doc -*-"?

John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 07:52:27 PM UTC, comment #29: 

are your 'should be shown for's for the disp function right?

Nicholas Jankowski <nrjank>
Group Member
Tue 30 Jan 2024 07:51:40 PM UTC, comment #28: 

As also mentioned by Rik, I am also in favor of consistency over Matlab compatibility here. The only Matlab compatible think I favor is a way to be able to get a different documentation for the class and the class constructor, which is currently not supported by Octave. Apart from this, I an quite happy with the way documentation differs in Octave from Matlab.

I fully agree with Rik's example below of how to deal with help documentation in the classdef

Andreas Bertsatos <pr0m1th3as>
Tue 30 Jan 2024 07:40:14 PM UTC, comment #27: 

For what it's worth, I favor consistency over Matlab-compatibility here.  Having coded for year's with Matlab's convention of having the first comment above the "function" keyword be the help text, I find I want to do the same when that "function" keyword is inside a classdef definition.  It's also the way I code in other languages like C++ where I put the overview of the function above its implementation.  Within the implementation I favor one-line comments explaining what is going on, rather than a treatise on the purpose of the function.

Here is the test function that I have been using (also attached).


classdef cdef_help
% class CDEF_HELP  A test class for checking help function
%
%   This comment block contains general help for the cdef_help class:
%
%   This general help text should be shown for "help cdef_help".
%
% @seealso{cdef_help, disp}
  properties
    % name: help for property NAME.
    % Type "help cdef_help.name"
    name
    age   % age: help for property AGE.  Type "help cdef_help.age"
  end

  methods

    function obj = cdef_help (n, a)
      % cdef_help: constructor help text
      %
      %  This help text should be shown for "help cdef_help.cdef_help".
      if (nargin ~= 2)
        obj.name = 'default';
        obj.age = 42;
      else
        obj.name = n;
        obj.age = a;
      end
    end

    % meth1: method help tex above function
    %
    %  This help text should be shown for "help cdef_help.meth1".
    function obj2 = meth1 (obj, n)
      obj2 = n + obj;
    end

    function obj2 = meth2 (obj, n)
      % meth2: method help tex below function
      %
      %  This help text should be shown for "help cdef_help.meth2".
      obj2 = n - obj;
    end

    % disp: method help text ABOVE function
    %
    %  This help text should be shown for "help cdef_help.meth1".
    function disp(obj)
      % disp: method help text BELOW function
      %
      %  This help text should be shown for "help cdef_help.meth1".
      fprintf('class name = "%s", age = %d\n', obj.name, obj.age)
    end
  end
end


The current behavior of Octave, when comments both ABOVE and BELOW the "function" keyword is to use the comment above.  I'm okay with that, but I also am less concerned about exact Matlab compatibility than others.

(file #55644)

Rik <rik5>
Group administrator
Tue 30 Jan 2024 07:09:18 PM UTC, comment #26: 

"My suggestion is that it favors
the text before rather than after the function's initial declaration."

Again, I don't see how we can do this for classdef methods and be Matlab compatible.

It seems best to me to just do the Matlab compatible thing and move on.

John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 06:50:26 PM UTC, comment #25: 

The documentation of the constructor in the ConfusionMatrixChart is not n actual documentation but merely comments, since in earlier version (7.2 and 8.2) that I work it didn't make any difference since you can't retrieve the constructor's help

>> help ConfusionMatrixChart.ConfusionMatrixChart
error: unknown package 'ConfusionMatrixChart'
error: called from
    <unknown>
    help at line 102 column 20

But I will make the necessary changes in time for Octave 9.1.

Although I explicitly use texinfo for help documentation, I don't think the get_help_text function should check for this. My suggestion is that it favors the text before rather than after the function's initial declaration. Personally, I prefer to have the documentation before and not inside the function. Perhaps it is just a matter of habit, since I am used to the way Octave functions' source files contain their documentation in contrast to MATLAB.

"It's always made sense to me to put that comment first, after the copyright statement."

I couldn't agree more with this statement.

"Or, are you suggesting the additional complication of checking the comment for a leading "-*- texinfo -*-" tag and only using (or preferring it) as the docstring if it is present?"

I don't know how much it adds to the complexity of the code or if it raises any computational speed issues, but that would be ideal, since it would be more robust in that it would return the 'appropriate' text block as documentation. Because, different users might have done things differently (currently or in the past) but if you have a "## -*- texinfo -*-" block, then you can be sure that this is the help documentation and not some code comment, regardless where the user might have placed it (before or after the "function" statement).


Andreas Bertsatos <pr0m1th3as>
Tue 30 Jan 2024 06:18:00 PM UTC, comment #24: 

"I suggest that it should support both in the sense that it looks in both places, so if some older classdef have the documentation before the function and not inside it, then get_help_text should return the one before instead of returning that documentation is not present."

I see the following method in the file statistics/inst/Classification/ConfusionMatrixChart.m (https://github.com/gnu-octave/statistics/blob/167b7e0c1b00b3e0ab887fbd16a420822dac8897/inst/Classification/ConfusionMatrixChart.m):


  methods (Access = public)
    ## class constructor
    ## inputs: axis handle, a confusion matrix, a list of class labels,
    ##         an array of optional property-value pairs.
    function this = ConfusionMatrixChart (hax, cm, cl, args)
      ## class initialization
      this.hax = hax;


and


    ## -*- texinfo -*-
    ## @deftypefn  {ConfusionMatrixChart} {} sortClasses (@var{cmc}, @var{order})
    ## Sort the classes of the @code{ConfusionMatrixChart} object @var{cmc}
    ## according to @var{order}.
    ##
    ## Valid values for @var{order} can be an array or cell array including
    ## the same class labels as @var{cm}, or a value like @code{"auto"},
    ## @code{"ascending-diagonal"}, @code{"descending-diagonal"} and
    ## @code{"cluster"}.
    ##
    ## @end deftypefn
    ##
    ## @seealso{confusionchart, linkage, pdist}
    function sortClasses (this, order)

      ## check the input parameters
      if (nargin != 2)
        print_usage ();
      endif


so if I understand correctly, the rules you are proposing would select "check the input parameters" as the docstring for the constructor and "check the input parameters" as the docstring for the sortClasses method.

Or, are you suggesting the additional complication of checking the comment for a leading "-*- texinfo -*-" tag and only using (or preferring it) as the docstring if it is present?  Currently, that tag is only used as a marker for deciding whether to process the docstring with the Texinfo formatter, not to decide whether it is a docstring.

"The other issue is that it feels a bit counter-intuitive to generally have the documentation for general functions before the function block in the m file, and in classdef files, requiring the documentation to be inside the function block."

For ordinary functions, I believe Matlab still selects either the first comment in a .m file, whether it is before or after the "function" keyword.  It's always made sense to me to put that comment first, after the copyright statement.

John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 04:43:01 PM UTC, comment #23: 

Perhaps I was not very clear about it. I suggest that it should support both in the sense that it looks in both places, so if some older classdef have the documentation before the function and not inside it, then get_help_text should return the one before instead of returning that documentation is not present.

I don't mind changing the docstrings place inside the classdef files in the statistics package, I am more concerned that if we get such a significant disruption in backwards compatibility, then I won't be able to support help for both Octave > 9 and Octave < 9. Unless, the current (Octave <=8.4) implementation of get_help_text already supports returning documentation from inside the method functions.

The other issue is that it feels a bit counter-intuitive to generally have the documentation for general functions before the function block in the m file, and in classdef files, requiring the documentation to be inside the function block.

comment #21:

> Which comment should be used for the method documentation if both are present?
>
> For compatibility with Matlab, that appears to be the one inside the function.
>
> For backward compatibility with previous versions of Octave, it would be the one before the function definition.
>
> I don't see how we can do both.
>

Andreas Bertsatos <pr0m1th3as>
Tue 30 Jan 2024 04:27:53 PM UTC, comment #22: 

sorry for the sloppy nomenclature.  I think i did a clear -c every time, but I'll double check.

first, this does work:

>> clear -c
>> help foobar_class/meth
  comment inside method


now, to avoid potentially leaving incorrect or misleading data, using the binary nomenclature, where 1 means the comment is there and 0 means i've deleted it, and a clear -c every time, here's a rerun of comment #16.

base case 1111111 (all present)


>> clear -c
help foobar_class
help foobar_class.foobar_class
help foobar_class.meth
help foobar_class.A
  comment prior to classdef keyword

  comment inside constructor

  comment inside method

  comment for property A


case 0111111  (removed prior-classdef)

>> clear -c
help foobar_class
help foobar_class.foobar_class
help foobar_class.meth
help foobar_class.A
  comment inside classdef block

    Documentation for foobar_class

  comment inside constructor

    Documentation for foobar_class/foobar_class

  comment inside method

  comment for property A


case 0110111 (prior classdef removed, also rem inside const.)

>> clear -c
help foobar_class
help foobar_class.foobar_class
help foobar_class.meth
help foobar_class.A
  comment inside classdef block

  comment inside classdef block

  comment inside method

  comment for property A


case 0110101 (prior classdef removed, also rem inside meth.)

>> clear -c
help foobar_class
help foobar_class.foobar_class
help foobar_class.meth
help foobar_class.A
  comment inside classdef block

  comment inside constructor

foobar_class/meth is a function.
    meth(obj)

  comment for property A



case 1011111 (only remove inside classdef)

clear -c
help foobar_class
help foobar_class.foobar_class
help foobar_class.meth
help foobar_class.A
  comment prior to classdef keyword

  comment inside constructor

  comment inside method

  comment for property A


case 1010111 (inside classdef removed, also rem. inside const.)

clear -c
help foobar_class
help foobar_class.foobar_class
help foobar_class.meth
help foobar_class.A
  comment prior to classdef keyword

  comment prior to classdef keyword

  comment inside method

  comment for property A


probably would be best to script a few specific cases to run for the 'desired' endstate before locking it down.

Nicholas Jankowski <nrjank>
Group Member
Tue 30 Jan 2024 04:23:31 PM UTC, comment #21: 

Which comment should be used for the method documentation if both are present?

For compatibility with Matlab, that appears to be the one inside the function.

For backward compatibility with previous versions of Octave, it would be the one before the function definition.

I don't see how we can do both.

John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 04:06:52 PM UTC, comment #20: 

Is it much trouble to add the functionality to retrieve the documentation from the constructor and the public methods both from inside the function block (as you propose) and just before the function block (which is the current behavior, so that it doesn't break backwards compatibility?

Andreas Bertsatos <pr0m1th3as>
Tue 30 Jan 2024 03:37:56 PM UTC, comment #19: 

Here is what I propose to do, regardless of any weird quirks of Matlab behavior:

The documentation for the class itself will be the first non-copyright comment at the top of the file prior to the classdef keyword or, if that is missing, the first comment inside the classdef block.

The documentation for the constructor and methods will be the first comment inside the function.  If that is missing, then the function will be undocumented.

The documentation for properties will be the comment preceding the property name in the properties block.

For "help classname" display the documentation for the class.  If that is empty, display the documentation for the constructor.

For "help classname.classname" display the documentation for the class constructor.  If that is empty but the class itself is documented, display that.

Does that make sense?  Is it at all close to Matlab behavior?  That's what my test case was trying to determine.




John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 03:26:39 PM UTC, comment #18: 

"i didn't run through all 2^7 options"

BUT wait, I wanted to see all possibilities!

So, for methods, it always grabs the comment inside the function, correct?

But for the constructor, it depends on whether there is a comment prior to the "classdef" keyword?  Am I getting that right?

I'm a bit confused by


now, removing the main 'prior' one and doing a clear -c:

    >> help foobar_class
      comment inside classdef block

    >> help foobar_class.foobar_class
      comment inside classdef block


and then


replacing it but removing 'inside method'

    >> help foobar_class
      comment inside classdef block

    >> help foobar_class.foobar_class
      comment inside constructor


In one case, "help foobar_class.foobar_class" returned the comment outside the constructor function and in the other case it did not?  Did you clear the class definition each time?

Maybe I should just post a full set of files and a complete script to run so that there is no confusion about whether "clear -c" was used?

Also, WTF is up with the output


>> help foobar_class.meth
foobar_class/meth is a function.
    meth(obj)


I was hopeful we were done with any syntax like "@cls/meth".

Does "help foobar_class/meth" work?

John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 03:16:18 PM UTC, comment #17: 


> What happens if you remove the "%% comment prior to classdef keyword" comment from the file?


sorry, crossing comments.  in case it isn't clear from how i described it.  that's the first full block in comment #16. (removing the main 'prior')

Nicholas Jankowski <nrjank>
Group Member
Tue 30 Jan 2024 03:13:31 PM UTC, comment #16: 

whoops, submitted the preview... the third one should have been meth not method (and snipping all the html links):


>> help foobar_class.meth
  comment inside method


now, removing the main 'prior' one and doing a clear -c:


>> help foobar_class
  comment inside classdef block

>> help foobar_class.foobar_class
  comment inside classdef block

>> help foobar_class.meth
  comment inside method

>> help foobar_class.A
  comment for property A


also removing 'inside constructor':


>> help foobar_class
  comment inside classdef block

>> help foobar_class.foobar_class
  comment inside classdef block

>> help foobar_class.meth
  comment inside method

>> help foobar_class.A
  comment for property A


replacing it but removing 'inside method'

>> help foobar_class
  comment inside classdef block

>> help foobar_class.foobar_class
  comment inside constructor

>> help foobar_class.meth
foobar_class/meth is a function.
    meth(obj)

>> help foobar_class.A
  comment for property A


replacing that and the 'prior to classdef keyword' (back to original state) but just removing 'inside classdef block'


>> help foobar_class
  comment prior to classdef keyword

>> help foobar_class.foobar_class
  comment inside constructor

>> help foobar_class.meth
  comment inside method

>> help foobar_class.A
  comment for property A


also removing 'inside constructor':


>> help foobar_class
  comment prior to classdef keyword

>> help foobar_class.foobar_class
  comment prior to classdef keyword

>> help foobar_class.meth
  comment inside method

>> help foobar_class.A
  comment for property A


7 comments here, so i didn't run through all 2^7 options. let me know if there are others that look important

Nicholas Jankowski <nrjank>
Group Member
Tue 30 Jan 2024 03:03:44 PM UTC, comment #15: 

OK, I mistyped the "help foobar_class.meth" command, but I'm assuming that it will return the "comment inside method" text given the other results.

Also, I see that properties can be documented in the classdef file, so I'll look at fixing that.  I'm not sure whether we are attaching any comment info to the property objects but it should be fairly straightforward to do that.

What happens if you remove the "%% comment prior to classdef keyword" comment from the file?  Does Matlab find the one inside the classdef block instead?

Regarding the comment


Of course, in Octave it is necessary that get_help_text looks for texinfo before the function because AFAIK all core functions and in many packages as well follow this template, i.e. the help docstring is right before the function declaration.


That is true for functions defined in separate files, but for classdef blocks, I don't think we need to attempt to do anything more than what Matlab does.  Let's not complicate things further.

John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 02:54:02 PM UTC, comment #14: 

matlab 2023b:


>> help foobar_class
  comment prior to classdef keyword

    <a href="matlab:doc foobar_class">Documentation for foobar_class</a>

>> help foobar_class.foobar_class
  comment inside constructor

    <a href="matlab:doc foobar_class">Documentation for foobar_class/foobar_class</a>

>> help foobar_class.method
foobar_class.method not found.

    <a href="matlab:docsearch foobar_class.method">Search the documentation for foobar_class.method</a>

>> help foobar_class.A
  comment for property <strong>A</strong>


Nicholas Jankowski <nrjank>
Group Member
Tue 30 Jan 2024 02:22:33 PM UTC, comment #13: 

"According to the matlab documentation [1], the function docs should be inside the function itself."

OK, but what does Matlab actually do?

Given a classdef file that contains


%% comment prior to classdef keyword
classdef foobar_class
  %% comment inside classdef block
  methods
    %% comment prior to constructor
    function obj = foobar_class ()
      %% comment inside constructor
    end
    %% comment prior to method
    function meth (obj)
      %% comment inside method
    end
  end
  properties
    %% comment for property A
    A = 1;
  end
end


What does the following produce?


help foobar_class
help foobar_class.foobar_class
help foobar_class.method
help foobar.A


IF any of the "comment prior to ..." comments are displayed, what happens if they are removed?

Does the behavior change if any of the "comment inside ..." comments are removed?

John W. Eaton <jwe>
Group administrator
Tue 30 Jan 2024 02:03:32 PM UTC, comment #12: 

containers.Map and inputParser at least has the texinfo documentation inside the function, so would work per the matlab standard.


I usually just add the functions as a section within the classdef main texinfo since previously the function documentation wouldnt display anyway.

But being able to document the actual function would be better :)

John Donoghue <lostbard>
Group Member
Mon 29 Jan 2024 10:26:33 PM UTC, comment #11: 

Although it is not clearly stated in the matlab documentation referenced by John, running the example class ('someClass') from this documentation in MATLAB R2022b uields the following

>> help someClass
  someClass Summary of this class goes here
    Detailed explanation goes here

    Documentation for someClass

>> help someClass.someClass
  Summary of constructor

    Documentation for someClass/someClass

>>

So making help and get_help_text behaving accordingly also fixes MATLAB compatibility. Of course, in Octave it is necessary that get_help_text looks for texinfo before the function because AFAIK all core functions and in many packages as well follow this template, i.e. the help docstring is right before the function declaration.

Andreas Bertsatos <pr0m1th3as>
Mon 29 Jan 2024 03:44:38 PM UTC, comment #10: 

According to the matlab documentation [1], the function docs should be inside the function itself.





[1] https://www.mathworks.com/help/matlab/matlab_prog/create-help-for-classes.html

John Donoghue <lostbard>
Group Member
Mon 29 Jan 2024 01:28:34 PM UTC, comment #9: 

In Octave, the help text below the classdef argument is parsed as the help text of the constructor. So if there is help just before the constructor it is ignored.
For example

classdef Foo
## help classdef
  properties
  ...
  end properties
  methods
    ## help constructor
    function this = Foo (this)
    ...
    endfunction
    ...
  endmethods
endclassdef

Does MATLAB distinguish between help classdef help text and constructor help text? For example

help Foo
  help classdef

help Foo.Foo
  help constructor

Even if this is not supported in MATLAB, I think it would be very convenient to have this feature in Octave, since we could have a help docstring for the classdef itself informing about properties and methods available in the classdef, and then have a separate help docstring about how to use the constructor including available Name/Value paired arguments etc.

Andreas Bertsatos <pr0m1th3as>
Mon 29 Jan 2024 09:35:40 AM UTC, comment #8: 

In Matlab R2023b, "help inputParser.addParameter" shows the help text for that method.
"help inputParser" and "help inputParser.inputParser" can both be used to show the help text for the constructor.

"help containers.Map.isKey" shows the help text for that method.
"help containers.Map" and "help containers.Map.Map" show the help text for the constructor.

Markus Mützel <mmuetzel>
Group administrator
Mon 29 Jan 2024 06:15:01 AM UTC, comment #7: 

Here is another attempt.  Now "help inputParser" and "help containers.Map" both work for me.  As far as I can tell, I didn't break anything from the previous version of the changeset.  Before pushing, however, we could probably use some tests.


(file #55639)

John W. Eaton <jwe>
Group administrator
Mon 29 Jan 2024 05:42:10 AM UTC, comment #6: 

I just noticed that although the change I posted does allow things like "help inputParser.addParameter" to work, it doesn't return any help text for "help inputParser" by itself.  I'll check that out.  I assume it should return the help text for the class constructor.  WDMD?

John W. Eaton <jwe>
Group administrator
Mon 29 Jan 2024 05:35:25 AM UTC, comment #5: 

Oops, I forgot to attach the file.  It should be linked in this comment.

(file #55638)

John W. Eaton <jwe>
Group administrator
Mon 29 Jan 2024 05:32:06 AM UTC, comment #4: 

With the attached changeset, both the help and which commands do a lot better job of looking up qualified names: pkg.cls.method, or pkg.fcn, or even just pkg or pkg.cls should all work now.

Opinions about making this change on stable before the release?  I also don't want to get into the never ending "just one more bug fix trap" but this one would probably be a noticeable improvement.

John W. Eaton <jwe>
Group administrator
Sun 28 Jan 2024 08:48:01 AM UTC, comment #3: 

I have made a simple classdef to demonstrate this issue without relying in any package.

It just makes a sinewave object with properties (frequency, amplitude, duration) and it has a constructor and a method to plot the sinewave, which contains its own help docstring.

to use the classdef

sw = sinewave (10, 2, 3);
plot (sw)

to demonstrate the bug with get_help_text

>> help sinewave
'sinewave' is a class constructor from the file /home/promitheas/Octave/sinewave.m

 -- OBJ = since (FREQ, AMPL, DUR)

     A sinewave object defined by its frequency, FREQ, and its
     amplitude, AMPL, and duration, DUR, in seconds.

Additional help for built-in functions and operators is
available in the online version of the manual.  Use the command
'doc <topic>' to search the manual index.

Help and information about Octave is also available on the WWW
at https://www.octave.org and via the help@octave.org
mailing list.
>> help sinewave.plot
'sinewave.plot' is a function from the file /usr/local/share/octave/7.2.0/m/plot/draw/plot.m

 -- plot (Y)
 -- plot (X, Y)
 -- plot (X, Y, FMT)
 -- plot (..., PROPERTY, VALUE, ...)
 -- plot (X1, Y1, ..., XN, YN)
 -- plot (HAX, ...)
 -- H = plot (...)
     Produce 2-D plots.

     Many different combinations of arguments are possible.  The
     simplest form is

          plot (Y)

     where the argument is taken as the set of Y coordinates and the X
     coordinates are taken to be the range '1:numel (Y)'.

     If more than one argument is given, they are interpreted as

          plot (Y, PROPERTY, VALUE, ...)

     or

          plot (X, Y, PROPERTY, VALUE, ...)

     or

          plot (X, Y, FMT, ...)

     and so on.  Any number of argument sets may appear.  The X and Y
     values are interpreted as follows:

        * If a single data argument is supplied, it is taken as the set
          of Y coordinates and the X coordinates are taken to be the
          indices of the elements, starting with 1.

        * If X and Y are scalars, a single point is plotted.

        * 'squeeze()' is applied to arguments with more than two
          dimensions, but no more than two singleton dimensions.

        * If both arguments are vectors, the elements of Y are plotted
          versus the elements of X.

        * If X is a vector and Y is a matrix, then the columns (or rows)
          of Y are plotted versus X.  (using whichever combination
          matches, with columns tried first.)

        * If the X is a matrix and Y is a vector, Y is plotted versus
          the columns (or rows) of X.  (using whichever combination
          matches, with columns tried first.)

        * If both arguments are matrices, the columns of Y are plotted
          versus the columns of X.  In this case, both matrices must
          have the same number of rows and columns and no attempt is
          made to transpose the arguments to make the number of rows
          match.

     Multiple property-value pairs may be specified, but they must
     appear in pairs.  These arguments are applied to the line objects
     drawn by 'plot'.  Useful properties to modify are "linestyle",
     "linewidth", "color", "marker", "markersize", "markeredgecolor",
     "markerfacecolor".  The full list of properties is documented at
     Line Properties.

     The FMT format argument can also be used to control the plot style.
     It is a string composed of four optional parts:
     "<linestyle><marker><color><;displayname;>".  When a marker is
     specified, but no linestyle, only the markers are plotted.
     Similarly, if a linestyle is specified, but no marker, then only
     lines are drawn.  If both are specified then lines and markers will
     be plotted.  If no FMT and no PROPERTY/VALUE pairs are given, then
     the default plot style is solid lines with no markers and the color
     determined by the "colororder" property of the current axes.

     Format arguments:

     linestyle

          '-'  Use solid lines (default).
          '--' Use dashed lines.
          ':'  Use dotted lines.
          '-.' Use dash-dotted lines.

     marker

          '+'  crosshair
          'o'  circle
          '*'  star
          '.'  point
          'x'  cross
          '|'  vertical line
          '_'  horizontal line
          's'  square
          'd'  diamond
          '^'  upward-facing triangle
          'v'  downward-facing triangle
          '>'  right-facing triangle
          '<'  left-facing triangle
          'p'  pentagram
          'h'  hexagram

     color

          'k', "black"    blacK
          'r', "red"      Red
          'g', "green"    Green
          'b', "blue"     Blue
          'y', "yellow"   Yellow
          'm',            Magenta
          "magenta"
          'c', "cyan"     Cyan
          'w', "white"    White

     ";displayname;"
          The text between semicolons is used to set the "displayname"
          property which determines the label used for the plot legend.

     The FMT argument may also be used to assign legend labels.  To do
     so, include the desired label between semicolons after the
     formatting sequence described above, e.g., "+b;Data Series 3;".
     Note that the last semicolon is required and Octave will generate
     an error if it is left out.

     Here are some plot examples:

          plot (x, y, "or", x, y2, x, y3, "m", x, y4, "+")

     This command will plot 'y' with red circles, 'y2' with solid lines,
     'y3' with solid magenta lines, and 'y4' with points displayed as
     '+'.

          plot (b, "*", "markersize", 10)

     This command will plot the data in the variable 'b', with points
     displayed as '*' and a marker size of 10.

          t = 0:0.1:6.3;
          plot (t, cos(t), "-;cos(t);", t, sin(t), "-b;sin(t);");

     This will plot the cosine and sine functions and label them
     accordingly in the legend.

     If the first argument HAX is an axes handle, then plot into this
     axes, rather than the current axes returned by 'gca'.

     The optional return value H is a vector of graphics handles to the
     created line objects.

     To save a plot, in one of several image formats such as PostScript
     or PNG, use the 'print' command.

     See also: axis, box, grid, hold, legend, title, xlabel, ylabel,
     xlim, ylim, ezplot, errorbar, fplot, line, plot3, polar, loglog,
     semilogx, semilogy, subplot.

Additional help for built-in functions and operators is
available in the online version of the manual.  Use the command
'doc <topic>' to search the manual index.

Help and information about Octave is also available on the WWW
at https://www.octave.org and via the help@octave.org
mailing list.



(file #55629)

Andreas Bertsatos <pr0m1th3as>
Sat 27 Jan 2024 02:19:51 PM UTC, comment #2: 

I have uploaded the two classdef files, but the statistics package is still required because they rely on other statistics functions to run. My example below also uses the fisheriris dataset which is part of the statistics package.

Is there any other way I can help with this?

(file #55622, file #55623)

Andreas Bertsatos <pr0m1th3as>
Sat 27 Jan 2024 01:01:29 PM UTC, comment #1: 

Could you please upload the classdef files necessary to reproduce without having to load a separate package?

John W. Eaton <jwe>
Group administrator
Sat 27 Jan 2024 12:41:08 PM UTC, original submission:  

When trying to parse the docstring from a class method, which is defined by a superclass, the get_help_text function returns the help docstring from the parent methods instead of the method in the actual class I am asking for.

For example, the CalinskiHarabaszEvaluation class derived from the ClusterCriterion class in the statistics package, which are derived from the handle superclass, has it own plot public method, which shadows the plot method from handle class when it is called. However, when trying to get the help docstring from this method (with either help or get_help_text functions), Octave returns the helpl docstring from core Octave plot function.

>> pkg load statistics
>> load fisheriris
>> eva = evalclusters(meas, "kmeans", "calinskiharabasz", "KList", [1:6]);
>> plot(eva)
ans = -34.638
>> class(eva)
ans = CalinskiHarabaszEvaluation
>> help CalinskiHarabaszEvaluation.plot
'CalinskiHarabaszEvaluation.plot' is a function from the file /usr/local/share/octave/7.2.0/m/plot/draw/plot.m

 -- plot (Y)
 -- plot (X, Y)
 -- plot (X, Y, FMT)
 -- plot (..., PROPERTY, VALUE, ...)
 -- plot (X1, Y1, ..., XN, YN)
 -- plot (HAX, ...)
 -- H = plot (...)
     Produce 2-D plots.

     Many different combinations of arguments are possible.  The
     simplest form is

          plot (Y)

     where the argument is taken as the set of Y coordinates and the X
     coordinates are taken to be the range '1:numel (Y)'.

     If more than one argument is given, they are interpreted as

          plot (Y, PROPERTY, VALUE, ...)

     or

          plot (X, Y, PROPERTY, VALUE, ...)

     or

          plot (X, Y, FMT, ...)

     and so on.  Any number of argument sets may appear.  The X and Y
     values are interpreted as follows:

        * If a single data argument is supplied, it is taken as the set
          of Y coordinates and the X coordinates are taken to be the
          indices of the elements, starting with 1.

        * If X and Y are scalars, a single point is plotted.

        * 'squeeze()' is applied to arguments with more than two
          dimensions, but no more than two singleton dimensions.

        * If both arguments are vectors, the elements of Y are plotted
          versus the elements of X.

        * If X is a vector and Y is a matrix, then the columns (or rows)
          of Y are plotted versus X.  (using whichever combination
          matches, with columns tried first.)

        * If the X is a matrix and Y is a vector, Y is plotted versus
          the columns (or rows) of X.  (using whichever combination
          matches, with columns tried first.)

        * If both arguments are matrices, the columns of Y are plotted
          versus the columns of X.  In this case, both matrices must
          have the same number of rows and columns and no attempt is
          made to transpose the arguments to make the number of rows
          match.

     Multiple property-value pairs may be specified, but they must
     appear in pairs.  These arguments are applied to the line objects
     drawn by 'plot'.  Useful properties to modify are "linestyle",
     "linewidth", "color", "marker", "markersize", "markeredgecolor",
     "markerfacecolor".  The full list of properties is documented at
     Line Properties.

     The FMT format argument can also be used to control the plot style.
     It is a string composed of four optional parts:
     "<linestyle><marker><color><;displayname;>".  When a marker is
     specified, but no linestyle, only the markers are plotted.
     Similarly, if a linestyle is specified, but no marker, then only
     lines are drawn.  If both are specified then lines and markers will
     be plotted.  If no FMT and no PROPERTY/VALUE pairs are given, then
     the default plot style is solid lines with no markers and the color
     determined by the "colororder" property of the current axes.

     Format arguments:

     linestyle

          '-'  Use solid lines (default).
          '--' Use dashed lines.
          ':'  Use dotted lines.
          '-.' Use dash-dotted lines.

     marker

          '+'  crosshair
          'o'  circle
          '*'  star
          '.'  point
          'x'  cross
          '|'  vertical line
          '_'  horizontal line
          's'  square
          'd'  diamond
          '^'  upward-facing triangle
          'v'  downward-facing triangle
          '>'  right-facing triangle
          '<'  left-facing triangle
          'p'  pentagram
          'h'  hexagram

     color

          'k', "black"    blacK
          'r', "red"      Red
          'g', "green"    Green
          'b', "blue"     Blue
          'y', "yellow"   Yellow
          'm',            Magenta
          "magenta"
          'c', "cyan"     Cyan
          'w', "white"    White

     ";displayname;"
          The text between semicolons is used to set the "displayname"
          property which determines the label used for the plot legend.

     The FMT argument may also be used to assign legend labels.  To do
     so, include the desired label between semicolons after the
     formatting sequence described above, e.g., "+b;Data Series 3;".
     Note that the last semicolon is required and Octave will generate
     an error if it is left out.

     Here are some plot examples:

          plot (x, y, "or", x, y2, x, y3, "m", x, y4, "+")

     This command will plot 'y' with red circles, 'y2' with solid lines,
     'y3' with solid magenta lines, and 'y4' with points displayed as
     '+'.

          plot (b, "*", "markersize", 10)

     This command will plot the data in the variable 'b', with points
     displayed as '*' and a marker size of 10.

          t = 0:0.1:6.3;
          plot (t, cos(t), "-;cos(t);", t, sin(t), "-b;sin(t);");

     This will plot the cosine and sine functions and label them
     accordingly in the legend.

     If the first argument HAX is an axes handle, then plot into this
     axes, rather than the current axes returned by 'gca'.

     The optional return value H is a vector of graphics handles to the
     created line objects.

     To save a plot, in one of several image formats such as PostScript
     or PNG, use the 'print' command.

     See also: axis, box, grid, hold, legend, title, xlabel, ylabel,
     xlim, ylim, ezplot, errorbar, fplot, line, plot3, polar, loglog,
     semilogx, semilogy, subplot.

Additional help for built-in functions and operators is
available in the online version of the manual.  Use the command
'doc <topic>' to search the manual index.

Help and information about Octave is also available on the WWW
at https://www.octave.org and via the help@octave.org
mailing list.
>>


Although in the CalinskiHarabaszEvaluation classdef, there is a texinfo dostring related to the plot method as shown below

    ...
    ## -*- texinfo -*-
    ## @deftypefn  {CalinskiHarabaszEvaluation} {} plot (@var{obj})
    ## @deftypefnx {CalinskiHarabaszEvaluation} {@var{h} =} plot (@var{obj})
    ##
    ## Plot the evaluation results.
    ##
    ## Plot the CriterionValues against InspectedK from the
    ## CalinskiHarabaszEvaluation, @var{obj}, to the current plot. It can also
    ## return a handle to the current plot.
    ##
    ## @end deftypefn
    function h = plot (this)
      yLabel = sprintf ("%s value", this.CriterionName);
      h = gca ();
      hold on;
      plot (this.InspectedK, this.CriterionValues, "bo-");
      plot (this.OptimalK, this.CriterionValues(this.OptimalIndex), "b*");
      xlabel ("number of clusters");
      ylabel (yLabel);
      hold off;
    endfunction
    ...


Andreas Bertsatos <pr0m1th3as>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #55662:  foobar.m added by rik5 (300B - text/x-objcsrc)
file #55644:  cdef_help.m added by rik5 (1KiB - text/x-objcsrc)
file #55639:  bug-65220-cset-v2.txt added by jwe (11KiB - text/plain)
file #55638:  bug-65220-cset.txt added by jwe (11KiB - text/plain)
file #55629:  sinewave.m added by pr0m1th3as (1KiB - text/x-objcsrc)
file #55622:  ClusterCriterion.m added by pr0m1th3as (8KiB - text/x-objcsrc)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by rik5 (Updated the item)
  • -email is unavailable- added by nrjank (Posted a comment)
  • -email is unavailable- added by lostbard (Posted a comment)
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by pr0m1th3as (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 23 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2024-02-05 rik5 StatusReady For Test Fixed
        Open/ClosedOpen Closed
    2024-02-05 jwe StatusIn Progress Ready For Test
    2024-02-04 jwe Attached File- Added classdef-doc-string-patch-v2.txt, #55664
    2024-02-03 jwe Attached File- Added classdef-doc-string-patch.txt, #55663
    2024-02-03 rik5 Attached File- Added foobar.m, #55662
        StatusFixed In Progress
        Open/ClosedClosed Open
    2024-02-03 rik5 StatusReady For Test Fixed
        Open/ClosedOpen Closed
        Fixed ReleaseNone 9.1.0
    2024-02-03 jwe StatusIn Progress Ready For Test
    2024-02-02 jwe StatusReady For Test In Progress
    2024-02-01 jwe StatusPatch Submitted Ready For Test
        Planned ReleaseNone 9.1.0
    2024-01-30 rik5 Attached File- Added cdef_help.m, #55644
    2024-01-30 nrjank Operating SystemGNU/Linux Any
    2024-01-29 jwe Attached File- Added bug-65220-cset-v2.txt, #55639
    2024-01-29 jwe Attached File- Added bug-65220-cset.txt, #55638
    2024-01-29 jwe StatusNone Patch Submitted
    2024-01-28 pr0m1th3as Attached File- Added sinewave.m, #55629
    2024-01-27 pr0m1th3as Attached File- Added ClusterCriterion.m, #55622
        Attached File- Added CalinskiHarabaszEvaluation.m, #55623

    Back to the top

    Powered by Savane 3.13-4b48.
    Corresponding source code