bugGNU Octave - Bugs: bug #64516, Document how optimset expands...

 
 

bug #64516: Document how optimset expands short option inputs to full option names

Submitter:  Liang Tang <lt1234>
Submitted:  Sat 05 Aug 2023 06:11:34 PM UTC
   
 
Category:  Documentation Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Documentation
Status:  Fixed Assigned to:  None
Originator Name:  lt1234 Open/Closed:  * Closed
Release:  * 8.2.0 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

Thu 10 Aug 2023 03:33:27 PM UTC, comment #27: 

agreed.  pushed docstring changes capturing those points as
http://hg.savannah.gnu.org/hgweb/octave/rev/120134e43537

Nicholas Jankowski <nrjank>
Group Member
Thu 10 Aug 2023 09:56:18 AM UTC, comment #26: 

This double-negative is confusing imho:

## Any non-standard field names in @var{old} are ignored when
## matching parameter names


Could we change this to a positive statement instead?
E.g.: "Option names expand only to names from the list of default options."
Or: "Only option names from the list of default options are considered when expanding short option names."

Markus Mützel <mmuetzel>
Group administrator
Thu 10 Aug 2023 09:46:49 AM UTC, comment #25: 

The documentation is now much better than before. Thank you for that change.
But imho, it should mention that option names are matched case-insensitive and that the matching uses the start of the default option names.

Markus Mützel <mmuetzel>
Group administrator
Wed 09 Aug 2023 08:11:21 PM UTC, comment #24: 

a patch was pushed over on bug #64525 that addresses the documentation issues mentioned in this report. marking as fixed and closing.  if any details were missed this can be reopened or detailed on the other report.

Nicholas Jankowski <nrjank>
Group Member
Mon 07 Aug 2023 06:13:58 PM UTC, comment #23: 

There is an actual Matlab incompatibility where short names in Octave cause only a warning to be emitted, and not an error.  See my recently filed bug #64525.  I have a fix for it.

Rik <rik5>
Group administrator
Mon 07 Aug 2023 04:58:45 PM UTC, comment #22: 

worth noting that in Matlab, arbitrary fields within an optimset returned struct is not supported. Fields added to the struct manually are removed by subsequent calls to optimset. (In matlab, they are really only intended to carry values of pre-defined parameters to the built in optimization routines, not as general parameter containers). 

Whether intentionally or unintentionally, Octave allows arbitrary parameters to be set, but compatibility dictates certain optimset matching behavior against the pre-defined parameter set. E.g., Matlab always expects optimset('w',5) to make the 'weights' field = 5, even if you manually add a 'w' field to the struct, so octave likely needs to follow suit

There is not any proposed change to any of the above behavior here, so better documentation is the key.  This would likely best occur in the text that appears in:
'help optimset'
'help optimget'


Neither help mentions anything about matching. optimset lists 'Valid Parameters' with no mention that this list can be expanded by other packages, and that that would change matching behavior. I don't see any other place in the Octave documentation (https://docs.octave.org/latest/) mentioning that behavior or where it should be added.

so as requested below, help text improvement suggestions for those two functions should address the immediate concern.

Nicholas Jankowski <nrjank>
Group Member
Mon 07 Aug 2023 01:17:37 PM UTC, comment #21: 

We are going in circles. To spell it out clearly again: This is a documentation issue. The current behavior needs to stay for compatibility with older code and with Matlab.

The only way to avoid errors in user code is to better document how those functions need to be used.
If no one (e.g., you) will work on improving the documentation, nothing will change.

Markus Mützel <mmuetzel>
Group administrator
Mon 07 Aug 2023 01:11:04 PM UTC, comment #20: 

Markus,

These are my replies.

My question is why you'd add custom fields to the options structure in the first place. <== options is a struct that enters analysis m files.  It is an easy vehicle to carry info into user defined function.  If this is not allowed, Octave should either stop me or ignore me.  My view is: once Octave accepts the added fields, they should be treated with the same family rule.  The example in my prior note indicated that they are not handled according to our communication (or known rules) in this bug report. 

I'd guess that doing that is the first user error. The second user error is probably to mix optimset with direct modifications of the options structure. <== Nothing would prevent this to occur.  matlab/octave are not strictly object oriented programming code.  Proper use of the short cut is not harmful and can be seen in lots of codes.  I understand the mindset of optimset/optimget.  All I can say is that it takes lots of discipline to follow when there is no control.

Liang Tang <lt1234>
Mon 07 Aug 2023 12:17:37 PM UTC, comment #19: 

My question is why you'd add custom fields to the options structure in the first place.
I'd guess that doing that is the first user error. The second user error is probably to mix optimset with direct modifications of the options structure.

I'm guessing that the option structure for the optimization functions was invented by the MathWorks before classdef was a thing. Otherwise, they'd probably created a class for which adding arbitrary fields would be an error.
For backward compatibility, we now need to live with how things are designed.

To get this back on track: Octave would definitely benefit from a better documentation of this.
I'm looking forward to your suggestions for an improved help text that would have avoided the current confusion for you.

Markus Mützel <mmuetzel>
Group administrator
Mon 07 Aug 2023 11:38:39 AM UTC, comment #18: 

Markus,

Typically, I assume "I don't know".  So I will bring up defaults of the software to find out what I don't know and what I need to know to use the software.  optimset is an example.

I mixed two things here: optimset & direct access to options struct.   

This is the basic issue:

a=optimset(); % create niter_check_tolfun = []
a.n=100;      % my own field
a=optimset(a, 'n', 200)  % try to change n later, not niter_check_tolfun. 
a.n
a.niter_check_tolfun

You see, in a, n=100 but niter_check_tolfun = 200.  There is no warning that n is replaced by niter_check_tolfun or there are two fields starting with n. So, I completely missed this. 

Liang Tang <lt1234>
Mon 07 Aug 2023 07:12:05 AM UTC, comment #17: 

Using Matlab R2023a:

>> optimset('O', @test)

ans =

  struct with fields:

        Display: []
    MaxFunEvals: []
        MaxIter: []
         TolFun: []
           TolX: []
    FunValCheck: []
      OutputFcn: @test
       PlotFcns: []


So for compatibility, option names need to be matched with just one single character if possible.


Re-reading the posts so far, I'm not sure if you really want to use `optimset` at all. It looks like you'd like to add parameters to some kind of configuration structure. Why aren't you using a plain `struct` instead of going though `optimset`?

Markus Mützel <mmuetzel>
Group administrator
Sun 06 Aug 2023 10:42:08 PM UTC, comment #16: 

Rik,

I briefly revisited the optimset.  This shows what I think I did wrong.  The right or better way seems to be

options=optimset('fmincon');
options=optimset(options, 'nxxx', 100);

options=optimset();  will bring up a superset of (useless) fields that potentially mess up something.  You might want to try in matlab on this. 

My past experiences with this type auto appending or conversion do suggest that there are some min number of characters, like three or four, before the software takes over.  So I wasn't ready for running into this with a single character.  I knew a single character field is a bad idea, not a good practice. Thanks. 




Liang Tang <lt1234>
Sun 06 Aug 2023 09:46:53 PM UTC, comment #15: 

Checking how Matlab handles this is a useful second opinion on desired behavior.

Matlab

1) emits an error if a short name is ambiguous (matches one or more possibilities)

2) does not issue any message or warning if a short name is unambiguous, and expands the short name to the full long name.

I agree with Markus that emitting a warning whenever a partial name is expanded would be very noisy, and is probably why Matlab has chosen not to do this.  I also agree that it is impossible within core Octave to document every option available because a new package, or even a new user function, could add potential options.

Currently there is no documentation about the expansion of short names to long names.  That should be fixed.

For the original bug reporter, I believe it would better to use the full name of options with optimset.  This makes for clearer code, and eliminates ambiguity.  If you intend to create your own options then I would choose long, meaningful option names in the same way that one chooses meaningful variable names.  The name 'n', even as a variable, could mean many things.  But, 'n_user_function_evals' or some such is very clear.

Rik <rik5>
Group administrator
Sun 06 Aug 2023 04:27:50 AM UTC, comment #14: 

If you'd like to do something like that, use the optimget function.

Markus Mützel <mmuetzel>
Group administrator
Sat 05 Aug 2023 10:13:48 PM UTC, comment #13: 

Let me try this:

>> options=optimset('tolf', 100)

options =

  scalar structure containing the fields:

    TolFun = 100

>> options.tolf

error: structure has no member 'tolf'

I think if the first command line is accepted, the second command line should also be accepted.

Liang Tang <lt1234>
Sat 05 Aug 2023 09:57:06 PM UTC, comment #12: 

Dmtri,

Is it always true below

You need a minimal unique sequence, so "t" would not work , but "ty" would.

If I define anything meets the min unique sequence,  it will be converted to internally recognized existing field.  If that is the case, there always a need to verify what is being done is what is intended.   W/o that, many of these type of conversions will drive the code execution to fall into the default handling loop, rather than being defined. 


Liang Tang <lt1234>
Sat 05 Aug 2023 08:02:41 PM UTC, comment #11: 

I'm not quite sure where that should be documented. Any package could add any number of options. Documenting all of them in the function inside Octave core is probably not feasible (or even desirable).
A short note that it is possible that packages might add to the list of options would probably a good idea though.

I don't think emitting a warning in case of an option being expanded is desirable. That would probably lead to a lot of noise in existing code.

Afaict, options expand only if they aren't ambiguous. I.e. with the set of options from Octave core, `Max` would not expand, but `maxf` would. I gathered that from reading the code. But that could probably also be better documented.

Documentation patches are always welcome.

Markus Mützel <mmuetzel>
Group administrator
Sat 05 Aug 2023 07:54:52 PM UTC, comment #10: 


comment #9:

> (3) I also did "T" as input, "T" is not replaced by anything. But there are tolx, tolfun, etc.   So there is a consistency issue in replace/substitute rule.  


You need a minimal unique sequence, so "t" would not work , but "ty" would:


octave:3> o=optimset('ty', 100)
o =

  scalar structure containing the fields:

    TypicalX = 100


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Sat 05 Aug 2023 07:51:02 PM UTC, comment #9: 

Markus,

Thanks for the suggestion.  I already replace "n" with a longer name.  

There are few things to consider:

(1) The information/document of the many added options are nowhere to find. The available document contains only a small subset of the list in the Dmitri's note.

(2) If n is replaced, there should be an information/warning message.

(3) I also did "T" as input, "T" is not replaced by anything. But there are tolx, tolfun, etc.   So there is a consistency issue in replace/substitute rule.

Liang Tang <lt1234>
Sat 05 Aug 2023 07:31:45 PM UTC, comment #8: 

From reading "help optimget" I thought that would not even be possible.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Sat 05 Aug 2023 07:28:46 PM UTC, comment #7: 

The optim package adds the options for the following functions to that list:

  • lsqlin
  • nonlin_residmin
  • nonlin_min
  • residmin_stat
  • lsqcurvefit
  • quadprog
  • vfzero
  • lsqnonlin
  • fmincon
  • powell


Afaict, that's intended.

Markus Mützel <mmuetzel>
Group administrator
Sat 05 Aug 2023 07:25:11 PM UTC, comment #6: 

IIUC, the function `optimset` matches input against all possible options returned by `__all_opts__()`. The optim package seems to add a lot of possible options. Compare the list that this function returns before and after `pkg load optim`.
Because `optimset` matches partial options (case-insensitive), you end up with a match for the single letter `n`. Try to use a longer name if you would like to use the structure returned by `optimset` with non-default fields.

Markus Mützel <mmuetzel>
Group administrator
Sat 05 Aug 2023 07:22:28 PM UTC, comment #5: 


octave:1> optimset

All possible optimization options:

  AutoScaling
  ComplexEqn
  Display
  FinDiffType
  FunValCheck
  GradObj
  Jacobian
  MaxFunEvals
  MaxIter
  OutputFcn
  TolFun
  TolX
  TypicalX
  Updating

octave:2> pkg load optim
octave:3> optimset

All possible optimization options:

  Algorithm
  AutoScaling
  complex_step_derivative_equc
  complex_step_derivative_f
  complex_step_derivative_inequc
  complex_step_derivative_objf
  ComplexEqn
  covd
  cpiv
  cstep
  debug
  df_equc_idx
  df_equc_pstruct
  df_inequc_idx
  df_inequc_pstruct
  df_pstruct
  dfdp
  diff_onesided
  diffp
  Display
  equc
  f_equc_idx
  f_equc_pstruct
  f_inequc_idx
  f_inequc_pstruct
  f_pstruct
  FinDiffRelStep
  FinDiffType
  fixed
  fract_prec
  FunValCheck
  grad_objf_pstruct
  GradConstr
  GradObj
  hessian_objf_pstruct
  HessianFcn
  inequc
  inverse_hessian
  iters_adjust_step
  iters_fixed_T
  Jacobian
  lbound
  lm_svd_feasible_alt_s
  max_fract_change
  max_rand_step
  MaxFunEvals
  MaxIter
  mu_T
  niter_check_tolfun
  objf_grad
  objf_hessian
  objf_pstruct
  objf_type
  octave_sqp_tolerance
  OutputFcn
  parallel_local
  parallel_net
  param_config
  param_dims
  param_order
  plot_cmd
  recover_state
  residuals
  ret_corp
  ret_covd
  ret_covp
  ret_dfdp
  save_state
  SearchDirections
  siman_log
  stoch_regain_constr
  T_init
  T_min
  TolFun
  TolX
  trace_steps
  TypicalX
  ubound
  Updating
  user_interaction
  weights

octave:4>


Not sure if this is a feature or a bug.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Sat 05 Aug 2023 07:11:27 PM UTC, comment #4: 

Right after the Octave start up and in command window:

>> options=optimset('n', 100)

options =

  scalar structure containing the fields:

    niter_check_tolfun = 100

>> which optimset

'optimset' is a function from the file C:\Octave\Octave-8.2.0\mingw64\share\octave\8.2.0\m\optimization\
optimset.m

>>


optim is loaded during starup.

Liang Tang <lt1234>
Sat 05 Aug 2023 07:09:47 PM UTC, comment #3: 

OK -- I can reproduce the problem. The optim package does something with this.

octave:1> options=optimset('n', 100)
warning: optimset: unrecognized option: n
warning: called from
    optimset>setoptionfields at line 187 column 9
    optimset at line 169 column 12

options =

  scalar structure containing the fields:

    n = 100

octave:2> pkg load optim
octave:3> options=optimset('n', 100)
options =

  scalar structure containing the fields:

    niter_check_tolfun = 100

octave:4> which optimset
'optimset' is a function from the file /usr/local/share/octave/9.0.0/m/optimization/optimset.m


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Sat 05 Aug 2023 06:59:15 PM UTC, comment #2: 

What version of octave do you use?
What does "which optimset" return on your computer?
On my computer I see:

>> which optimset
'optimset' is a function from the file /app/share/octave/8.2.0/m/optimization/optimset.m
>> options=optimset('n', 100)
warning: optimset: unrecognized option: n
warning: called from
    optimset>setoptionfields at line 187 column 9
    optimset at line 169 column 12

options =

  scalar structure containing the fields:

    n = 100


In any case optimset does case-insensitive autocopletion, e.g.:


>> options=optimset('j', 'on')
options =

  scalar structure containing the fields:

    Jacobian = on


but "niter_check_tolfun" is not a valid option.

Dmitri.
--




Dmitri A. Sergatskov <dasergatskov>
Sat 05 Aug 2023 06:56:55 PM UTC, comment #1: 

I can't reproduce with Octave 8.2.0:

>> options=optimset('n', 100)
warning: optimset: unrecognized option: n
warning: called from
    optimset>setoptionfields at line 187 column 9
    optimset at line 169 column 12

options =

  scalar structure containing the fields:

    n = 100

>> version
ans = 8.2.0



What does `which optimset` return for you?

Markus Mützel <mmuetzel>
Group administrator
Sat 05 Aug 2023 06:11:34 PM UTC, original submission:  


I use optimset to add a new entry to the options struct.  Entry "n" got into the options as "niter_check_tolfun" silently. 

I cannot find the optimset documentation related to niter_check_tolfun.   Therefore, I don't know if the output below is expected. 

Thanks,

>> options=optimset('n', 100)

options =

  scalar structure containing the fields:

    niter_check_tolfun = 100

Liang Tang <lt1234>

 

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

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by nrjank (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by dasergatskov (Posted a comment)
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by lt1234 (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 14 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2023-08-10 nrjank StatusIn Progress Fixed
        Open/ClosedOpen Closed
    2023-08-10 mmuetzel StatusFixed In Progress
        Open/ClosedClosed Open
    2023-08-09 nrjank Open/ClosedOpen Closed
    2023-08-09 nrjank StatusConfirmed Fixed
        Fixed ReleaseNone 9.1.0
        Planned ReleaseNone 9.1.0
    2023-08-06 rik5 Summaryoptimset silently replace user defined &quot;n&quot; with &quot;niter_check_tolfun&quot; Document how optimset expands short option inputs to full option names
    2023-08-05 mmuetzel CategoryOctave Function Documentation
        Item GroupIncorrect Result Documentation
        StatusNeed Info Confirmed
        Operating SystemMicrosoft Windows Any
    2023-08-05 mmuetzel StatusNone Need Info

    Back to the top

    Powered by Savane 3.13-599c.
    Corresponding source code