bugGNU Octave - Bugs: bug #53817, optim package: nonlin_residmin()...

 
 

bug #53817: optim package: nonlin_residmin() fails at call to svd()

Submitter:  Georg Wiora <gwiora>
Submitted:  Thu 03 May 2018 07:48:38 AM UTC
   
 
Category:  Octave Package Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Regression
Status:  Fixed Assigned to:  None
Originator Name:  gwiora Open/Closed:  * Closed
Release:  * 4.4.0 Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sat 05 May 2018 06:52:30 PM UTC, comment #9: 

Thanks for working this out, I've pushed your fix. Probably a new release should be made for 4.4, but I won't find time until next weekend.

Olaf Till <i7tiol>
Group Member
Fri 04 May 2018 01:35:24 PM UTC, comment #8: 

Who is listed as the maintainer for the optim package?  It would be best to reach out via e-mail and point them to this bug.  The patch is, indeed, very simple so should be quick to apply.

Rik <rik5>
Group administrator
Fri 04 May 2018 12:41:37 PM UTC, comment #7: 

You are right Michael. I have changed line 205 to

[prt,s,v]=svd(prt,"econ");


and tested it successfully with 4.2.2 and 4.4.0. Patched version is attached.

(file #44088)

Georg Wiora <gwiora>
Fri 04 May 2018 07:55:38 AM UTC, comment #6: 

No, this shouldn't need to be so complicated: according to the documentation for 4.2.2 (https://octave.org/doc/v4.2.2/Matrix-Factorizations.html#Matrix-Factorizations): "If given a second argument, svd returns an economy-sized decomposition, eliminating the unnecessary rows or columns of U or V." I interpret this to mean any second argument.

4.4.0 (https://octave.org/doc/interpreter/Matrix-Factorizations.html#Matrix-Factorizations) says "When given a second argument that is not 0, svd returns an economy-sized decomposition, eliminating the unnecessary rows or columns of U or V." So to me it seems that it should suffice to just change the 0 to a 1 (or anything else) in the call to svd, as I said in my previous comment, no need to switch on the version. It is just an unhappy coincidence that the optim package used the specific value 0 that later gained a special meaning, when it could also have used anything else.

Michael Leitner <mleitner>
Fri 04 May 2018 07:19:57 AM UTC, comment #5: 

Thanks for your clarifications! I recommend the following patch to _lm_svd_.m to keep compatibility with pre 4.4.0 octave versions:


% Check octave version
if all(str2num(cell2mat(strsplit(version(),".")')) >= [4;4;0])
  % 2018-May-04: Adapted to octave 4.4.0:
  % The meaning of second argument was changed for
  % matlab compatibility
  [prt,s,v]=svd(prt,"econ");
else
  % Octave syntax before 4.4.0
  [prt,s,v]=svd(prt,0);
endif


Patched file is attached.

Can anyone move this bug to the optim package? Does anyone know if the maintainer is still active?

(file #44080)

Georg Wiora <gwiora>
Fri 04 May 2018 03:45:51 AM UTC, comment #4: 

The change in syntax for svd was made for Matlab compatibility.  If you always want the economy-sized decomposition use 'econ' as the second argument as in


[U,S,V] = svd (A, 'econ')



Rik <rik5>
Group administrator
Thu 03 May 2018 08:27:01 PM UTC, comment #3: 

Actually, the returned matrices as you report them for version 4.2.0 correspond to the "economy-sized" decomposition (with square matrix S, but in the general case the larger of U or V non-square), while those for 4.4.0 correspond to the proper svd (with generally non-square matrix S, but square U and V). The difference is just due to the fact that (according to the documentation) between 4.2.2 and 4.4.0 a fourth way of calling svd was introduced, namely


[U, S, V] = svd (A, 0)


Specifically giving the number zero as second argument makes the algorithm decide which version to return. Honestly, I do not see where this should be necessary, and incidentially the optim package seems to use just this number zero to request the economy-sized decomposition, as it was returned up to 4.2.2, but which now received a special meaning. So instead of your proposed modification, if you just change the computation of the svd to


[prt,s,v]=svd(prt,1);


that should work, I think.

Michael Leitner <mleitner>
Thu 03 May 2018 08:10:57 AM UTC, comment #2: 

Here comes my workaround for _lm_svd_.m in package optim:

**HACK****
place this at line 205 in _lm_svd_.m

    [prt,s,v]=svd(prt,0);
    %% HACK: The matrices for s and v should be square but are returned non square by current svd implementation.
    s_size = min(size(s));
    s = s(1:s_size,1:s_size);
    v = v(:,1:s_size);


I also attached a patched copy of the function. I guess the causing problem in svd() should be easy to fix.

(file #44068)

Georg Wiora <gwiora>
Thu 03 May 2018 07:50:23 AM UTC, comment #1: 

Sorry for the typo: The second code block labeled "Version 4.4.0" shows the correct results from version 4.2.0!

Georg Wiora <gwiora>
Thu 03 May 2018 07:48:38 AM UTC, original submission:  

Since octave 4.4.0 nonlin_residmin() from package optim fails in my application at a call svd() function in octave core. In octave 4.2.2 this function was working perfectly.

Because package optim has not changed in the new release, it is very likely that svd() is producing different results now.


More precisely the error happens in file _lm_svd_ at line 230 ...\share\octave\packages\optim-1.5.2\private\__lm_svd__.m :


 tp1 = (v * (g .* ser)) .* nrm;

error: __lm_svd__: operator *: nonconformant arguments (op1 is 9x9, op2 is 4x1)
error: called from
    __lm_svd__ at line 230 column 11
    __nonlin_residmin__ at line 1128 column 21
    nonlin_residmin at line 98 column 21
    MyOptimizeFunction at ...


I have compared the results of two runs in 4.2.2 and 4.4.0 and found a difference in the return values of svd at _lm_svd_ line  205 at the following call:

[prt,s,v]=svd(prt,0);



Version 4.4.0 returns the wrong matrix size (non square) for result s (second result) and v (third result):

s =
Diagonal Matrix

  2.0000e+000            0            0            0            0            0            0            0            0
            0  1.6727e-003            0            0            0            0            0            0            0
            0            0  3.4258e-004            0            0            0            0            0            0
            0            0            0  1.3400e-017            0            0            0            0            0

v =
  -0.50000   0.49646  -0.16368   0.69046   0.00000   0.00000   0.00000   0.00000   0.00000
  -0.50000   0.50352   0.16595  -0.68478   0.00000   0.00000   0.00000   0.00000   0.00000
  -0.50000  -0.50249   0.68649   0.16196   0.00000   0.00000   0.00000   0.00000   0.00000
   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000  -1.00000
   0.00000   0.00000   0.00000   0.00000   1.00000   0.00000   0.00000   0.00000   0.00000
   0.00000   0.00000   0.00000   0.00000   0.00000   1.00000   0.00000   0.00000   0.00000
   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000   1.00000   0.00000   0.00000
   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000   0.00000   1.00000   0.00000
  -0.50000  -0.49749  -0.68877  -0.16764   0.00000   0.00000   0.00000   0.00000   0.00000


Version 4.4.0 returns:

s =
Diagonal Matrix

  2.0000e+000            0            0            0
            0  1.6727e-003            0            0
            0            0  3.4258e-004            0
            0            0            0  1.3400e-017

v =
  -0.50000   0.49646  -0.16368   0.69046
  -0.50000   0.50352   0.16595  -0.68478
  -0.50000  -0.50249   0.68649   0.16196
   0.00000   0.00000   0.00000   0.00000
   0.00000   0.00000   0.00000   0.00000
   0.00000   0.00000   0.00000   0.00000
   0.00000   0.00000   0.00000   0.00000
   0.00000   0.00000   0.00000   0.00000
  -0.50000  -0.49749  -0.68877  -0.16764


As you see the numbers are correct, but the matrices have extra columns.

I will implement a fix in my copy of "__lm_svd__.m" and see if it works then.

Georg Wiora <gwiora>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #44088:  __lm_svd__.m added by gwiora (20KiB - application/octet-stream - Patched version with minimal patch.)
file #44080:  __lm_svd__.m added by gwiora (20KiB - application/octet-stream - Patched version reflecting syntax changes in 4.4.0)
file #44068:  __lm_svd__.m added by gwiora (20KiB - application/octet-stream - Patched function for optim package to work with broken svd() function.)

 

Depends on the following items: None found

Digest:
   bug dependencies.

 

Carbon-Copy List
  • -email is unavailable- added by i7tiol (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by mleitner (Posted a comment)
  • -email is unavailable- added by gwiora (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 10 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2018-05-07 mmuetzel Dependencies- bugs #53833 is dependent
    2018-05-05 i7tiol StatusPatch Reviewed Fixed
        Open/ClosedOpen Closed
    2018-05-04 rik5 CategoryOctave Function Octave Package
        StatusNone Patch Reviewed
        Operating SystemMicrosoft Windows Any
        Summarynonlin_residmin() fails at call to svd() optim package: nonlin_residmin() fails at call to svd()
    2018-05-04 gwiora Attached File- Added _lm_svd_.m, #44088
    2018-05-04 gwiora Attached File- Added _lm_svd_.m, #44080
    2018-05-03 gwiora Attached File- Added _lm_svd_.m, #44068

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code