From octave-maintainers-request at bevo dot che dot wisc dot edu Thu Sep 7 19:34:22 2000 Subject: Re: [PATCH] Add min/max tests. (4/4) From: Paul Kienzle To: ejr at EECS dot Berkeley dot EDU, jwe@bevo.che.wisc.edu Cc: octave-maintainers at bevo dot che dot wisc dot edu Date: Fri, 08 Sep 2000 01:26:46 +0100 John W. Eaton writes: >On 5-Sep-2000, I wrote > >| How about >| >| min (abs (x), abs (y)) >| >| ? > >as a suggestion for how to explicitly state that you want to find the >numbers with the minimum magnitudes. After sending it, I realized >that this is not really what you want, since it returns the minimum >magnitudes, not the NUMBERS with the minimum magnitudes. So, I think >what is really needed is some way to tell the min and max funtions >what comparison operation (or function) to use. That would allow the >programmer to clearly state his intention instead of relying on some >convention that can cause trouble when there are mixed types or the >potential for automatic data type conversions to occur. For the cases where you need a nonstandard comparison, you could easily write a specialized function. For example, for magnitude: function z=minmag(x,y) z=x(:); zi=find(abs(x)>abs(y)); do_fortran_indexing = 1; z(zi) = y(zi); z = reshape(z,size(x)); endfunction To make it completely proper is a bit more work. You must protect the do_fortran_indexing state. You must handle 0, 1, 2, or many arguments, and for one argument, you must handle row/column vectors separately from matrices. The following should do it (though more testing is required): function [z, zi] = minmag(x, y, ...) if nargin == 0 usage("[z,zi]=minmag(x) or z=minmag(x1,x2,...)"); elseif nargin == 1 [z, zi] = min(abs(x)); [nr, nc] = size(x); if (nr == 1 || nc == 1) z(zi) = x(zi); else dfi = do_fortran_indexing; unwind_protect do_fortran_indexing = 1; z = x(zi + [0:nc-1]*nr); unwind_protect_cleanup do_fortran_indexing = dfi; end_unwind_protect endif else dfi = do_fortran_indexing; unwind_protect do_fortran_indexing = 1; z = x(:); idx = find(abs(x) > abs(y)); z(idx) = y(idx); z = reshape(z, size(x)); unwind_protect_cleanup do_fortran_indexing = dfi; end_unwind_protect if nargin > 2 z = minmag(z, all_va_args); endif endif endfunction > >Also, if it were up to me (or if I could do it over again) I would >want to avoid the problem that results from min, max, and other >functions working on columns of a matrix except when the matrix >happens to have only one row. No arguments there. > >jwe > > >