[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: 3.2 status report
From: |
Jaroslav Hajek |
Subject: |
Re: 3.2 status report |
Date: |
Wed, 6 Aug 2008 16:51:03 +0200 |
On Wed, Aug 6, 2008 at 4:17 PM, John W. Eaton <address@hidden> wrote:
> On 6-Aug-2008, Jaroslav Hajek wrote:
>
> | OK, I'll make this a priority. I'm currently in the process of
> | rewriting the HYBRJ driver from MINPACK into an m-file. It should not
> | be that hard, because QR factorization and QR rank-1 update are
> | readily available in Octave. The remaining building block is dogleg,
> | which could possibly be wrapped (libcruft/minpack/dogleg.f) but I have
> | a feeling that a m-file rewrite should also be simple, since the loops
> | in there are only employed for backsubs and level-1 ops. I'll try
> | submit first changesets to my repo soon, hopefully tomorrow or
> | tonight.
> | What we win by the rewrite is better clarity and maintainability,
> | automatic ability to work in single precision, and reentrancy. We lose
> | some memory efficiency (instead of compact QR storage, normal QR will
> | be used) and probably suffer a negligible performance loss
> | (there might be even a win for big dense problems because we call
> | LAPACK's blocked QR instead of the minpack's unblocked version).
>
> I don't object to a change like this if the performance hit is not too
> large. If it is, then perhaps we should consider rewriting it as a
> template-based C++ function or class?
>
I don't expect a big performance hit, if any (but I might be
surprised). And having fsolve and lsqnonlin in an m-file form means
interested people can more easily experiment. There's a number of
magical constants and other gotchas in the code, and I'm sure there is
room for improvements or alternative strategies.
> | If you just want a quickfix for the existing code, then go ahead.
> | Perhaps it is too late to get such a big change into 3.2.x - I intend
> | to get rid of the whole libcruft/minpack, for example.
>
> All I'm really interested in at the moment is to make the interface
> compatible. I think that is a separate issue from how the internals
> work, so our changes should not be overlapping much.
>
> jwe
>
OK, so there's no problem. You could probably use my optimget, but
that's a simple several-liner. Also, I made a simple change to
optimset, which also breaks Matlab compatibility, but I think it pays
off terribly:
Matlab's optimset returns always a structure with all possible
optimization options, the unspecfied ones set to []. I want it to omit
the unspecified fields and handle them in optimget (the difference is
trivial, actually). When operating with the options structures only
via optimget/optimset (which should be the preferable way), there
won't be any difference. And a conversion is trivial (in fact the
Matlab's style will still work if simply imported into Octave).
The reason for this change is that Matlab's choice makes the structure
visually useless: if you dump it on the screen, the relevant options
are hindered by a flood of empty fields which you're completely not
interested in (and sometimes they don't even make sense). I really
don't understand why the Matlab people made this choice.
Thus, there is no simple way to inspect what options a structure
actually contains.
I attach a patch for optimset, as well as optimget.
regards
--
RNDr. Jaroslav Hajek
computing expert
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz
diff --git a/scripts/optimization/optimset.m b/scripts/optimization/optimset.m
--- a/scripts/optimization/optimset.m
+++ b/scripts/optimization/optimset.m
@@ -45,18 +45,16 @@
tmp = opts';
disp (struct (tmp{:}));
else
- ## Return structure with empty values.
- t1 = opts(:,1)';
- t2 = cell (size (t1));
- tmp = [t1; t2];
- retval = struct (tmp{:});
+ ## Return empty structure.
+ ## We're incompatible with Matlab at this point.
+ retval = struct ();
endif
elseif (nargs == 1 && ischar (varargin{1}))
## Return defaults for named function.
fcn = varargin{1};
optfcn = sprintf ("__%s_defopts__", fcn);
if (exist (optfcn))
- retval = optimset (optimset (), feval (optfcn));
+ retval = optimset (struct (), feval (optfcn));
else
error ("no defaults for function `%s'", fcn);
endif
@@ -65,24 +63,21 @@
## to ensure that the field names are expected?
old = varargin{1};
new = varargin{2};
- fnames = fieldnames (old);
for [val, key] = new
- mask = strcmpi (fnames, key);
- if (any (mask))
- key = fnames (mask);
- endif
old.(key) = val;
endfor
retval = old;
- elseif (rem (nargs, 2) && isstruct (varargin{1}))
- ## Set values in old from name/value pairs.
- retval = optimset (varargin{1}, struct (varargin{2:end}));
- elseif (rem (nargs, 2) == 0)
- ## Create struct. Default values are replaced by those specified by
- ## name/value pairs.
- retval = optimset (optimset (), struct (varargin{:}));
else
- print_usage ();
+ if (rem (nargs, 2) && isstruct (varargin{1}))
+ ## Set values in old from name/value pairs.
+ s1 = varargin{1}; op = varargin(2:end);
+ elseif (rem (nargs, 2) == 0)
+ ## Create struct. Default values are replaced by those specified by
+ ## name/value pairs.
+ s1 = struct (); op = varargin(:);
+ else
+ print_usage ();
+ endif
endif
endfunction
function retval = optimget (options, parname, default)
if (isfield (options, parname))
retval = options.(parname);
elseif (nargin > 2)
retval = default;
else
retval = [];
endif
endfunction