|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 - 3 | Next > |
|
|
More New Functions: findfigs.m, isfloat.m, genvarname.mAttached are three new functions. Essentially now I'm just going
through the list of functions in matlab that are missing in octave and writing the low hanging fruit. Have a good day, Bill # HG changeset patch # User bill@... # Date 1205199789 14400 # Node ID a04d848ac6c371575205cbc130ed75035f2e9e4b # Parent 2e72daff62ba3d194850fff4e519d23a464c45e0 genvarname.m, isfloat.m, findfigs.m: new functions diff -r 2e72daff62ba -r a04d848ac6c3 scripts/ChangeLog --- a/scripts/ChangeLog Mon Mar 10 20:19:17 2008 -0400 +++ b/scripts/ChangeLog Mon Mar 10 21:43:09 2008 -0400 @@ -1,3 +1,8 @@ 2008-03-08 Bill Denney <bill@... +2008-03-10 Bill Denney <bill@...> + + * general/genvarname.m, plot/findfigs.m, general/isfloat.m: new + functions + 2008-03-08 Bill Denney <bill@...> * geometry/rectint.m: vectorize and add more tests diff -r 2e72daff62ba -r a04d848ac6c3 scripts/general/genvarname.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/general/genvarname.m Mon Mar 10 21:43:09 2008 -0400 @@ -0,0 +1,94 @@ +## Copyright (C) 2008 Bill Denney +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{varname} =} findfigs (@var{str}) +## @deftypefnx {Function File} {@var{varname} =} findfigs (@var{str}, @var{exclusions}) +## Create unique variable(s) from @var{str}. If @var{exclusions} is +## given, then the variable(s) will be unique to each other and to +## @var{exclusions} (@var{exclusions} may be either a string or a cellstr). +## +## If @var{str} is a cellstr, then a unique variable is created for each +## cell in @var{str}. +## @seealso{isvarname, exist, tmpnam} +## @end deftypefn + +## Author: Bill Denney <bill@...> + +function varname = genvarname (str, exclusions) + + strinput = ischar (str); + ## Process the inputs + if (nargin < 2) + exclusions = {}; + elseif ischar (exclusions) + if (rows (exclusions) != 1) + error ("genvarname: if more than one exclusion is given, it must be a cellstr") + endif + exclusions = {exclusions}; + elseif (! iscellstr (exclusions)) + error ("genvarname: exclusions must be a string or a cellstr") + endif + if ischar (str) + if (rows (str) != 1) + error ("genvarname: if more than one str is given, it must be a cellstr") + endif + str = {str}; + elseif (! iscellstr (str)) + error ("genvarname: str must be a string or a cellstr") + endif + + varname = cell (size (str)); + for i = 1:numel (str) + varname(i) = str(i); + idx = 0; + while any (strcmp (varname{i}, exclusions)) + idx++; + varname{i} = sprintf("%s%d", str{i}, idx); + endwhile + exclusions(end+1) = varname(i); + endfor + + if strinput + varname = varname{1}; + endif + +endfunction + +## Tests +## a single argument +%!assert(genvarname("a"), "a") +## a single argument with a non-conflicting exception +%!assert(genvarname("a", "b"), "a") +## a single argument with a conflicting exception +%!assert(genvarname("a", "a"), "a1") +## a single argument as a cell +%!assert(genvarname({"a"}), {"a"}) +%!assert(genvarname({"a"}, "b"), {"a"}) +%!assert(genvarname({"a"}, {"b"}), {"a"}) +%!assert(genvarname({"a"}, "a"), {"a1"}) +%!assert(genvarname({"a"}, {"a"}), {"a1"}) +## Test different arguments +## orientation +%!assert(genvarname({"a" "b"}), {"a" "b"}) +%!assert(genvarname({"a";"b"}), {"a";"b"}) +%!assert(genvarname({"a" "a"}), {"a" "a1"}) +## more than one repetition +%!assert(genvarname({"a" "a" "a"}), {"a" "a1" "a2"}) +## more than one repetition not in order +%!assert(genvarname({"a" "b" "a" "b" "a"}), {"a" "b" "a1" "b1" "a2"}) diff -r 2e72daff62ba -r a04d848ac6c3 scripts/general/isfloat.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/general/isfloat.m Mon Mar 10 21:43:09 2008 -0400 @@ -0,0 +1,43 @@ +## Copyright (C) 2008 Bill Denney +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{b} =} isfloat (@var{a}) +## Return true if @var{a} is a floating point data type (single, double) +## @seealso{isnumeric, isinteger, class, isa} +## @end deftypefn + +## Author: Bill Denney <bill@...> + +function b = isfloat (a) + + b = isa (a, "double") || isa (a, "single"); + +endfunction + +## Tests +%!assert(isfloat(1), true()) +%!assert(isfloat([1 1]), true()) +%!assert(isfloat([1;1]), true()) +%!assert(isfloat([1 1;1 1]), true()) +%!assert(isfloat(int8(1)), false()) +%!assert(isfloat(uint8(1)), false()) +%!assert(isfloat(true()), false()) +%!assert(isfloat('a'), false()) +%!assert(isfloat("a"), false()) +%!assert(isfloat("ab"), false()) diff -r 2e72daff62ba -r a04d848ac6c3 scripts/plot/findfigs.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/findfigs.m Mon Mar 10 21:43:09 2008 -0400 @@ -0,0 +1,63 @@ +## Copyright (C) 2008 Bill Denney +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} findfigs () +## Find all figures that are currently visible and off the screen and +## move them onto the screen. +## @seealso{figure, get, set} +## @end deftypefn + +## Author: Bill Denney <bill@...> + +function findfigs () + + figh = get (0, "children"); + screensize = get (0, "monitorpositions"); + + ## give the monitor a margin so that the figure must not just + ## marginally be on the monitor. + margin = 10; + screensize(1:2) += margin; + screensize(3:4) -= margin; + + for i = 1:numel (figh) + if strcmp (get (figh(i), "visible"), "on") + pos = get (figh(i), "position"); + ## Test if (in order): + ## The left side is outside the right side of the screen + ## The bottom is above the top of the screen + ## The right side is outside the left of the screen + ## the top is below the bottom of the screen + if ((pos(1) > screensize(3)) | + (pos(2) > screensize(4)) | + (pos(1)+pos(3) < screensize(1)) | + (pos(2)+pos(4) < screensize(2))) + + ## the new position will be at the bottom left of the screen + ## (all moved figures will overlap). The bottom left is chosen + ## instead of the top left because that allows for the unknown + ## amount of space for the menu bar and the title bar. + pos(1) = screensize(1); + pos(2) = screensize(2); + set (figh(i), "position", pos); + endif + endif + endfor + +endfunction |
|
|
Q: Low hanging fruit?On Mar 10, 2008, at 9:47 PM, Bill Denney wrote: > Attached are three new functions. Essentially now I'm just going > through the list of functions in matlab that are missing in octave > and writing the low hanging fruit. > > Have a good day, > > Bill Bill, Any chance you (or anyone else) have compiled a list of "low hanging fruit"? I expect there are a few individuals who would like to contribute to that effort. Personally, I'd be interested in writing some m-files during my spare time. Ben |
|
|
Re: Q: Low hanging fruit?On Mar 10, 2008, at 10:04 PM, Ben Abbott wrote: > > On Mar 10, 2008, at 9:47 PM, Bill Denney wrote: > >> Attached are three new functions. Essentially now I'm just going >> through the list of functions in matlab that are missing in octave >> and writing the low hanging fruit. >> >> Have a good day, >> >> Bill > > Bill, > > Any chance you (or anyone else) have compiled a list of "low hanging > fruit"? > > I expect there are a few individuals who would like to contribute to > that effort. > > Personally, I'd be interested in writing some m-files during my > spare time. > > Ben I don't know about a list of low hanging fruit, but I have one you could work on (or I should just stop being lazy and do it myself). The image processing toolbox function 'edge' does not have a *true* canny edge detector. There is a non-standard option called 'andy' that is similar to the canny edge detector, but isn't quite it. That is the only edge method still missing from the octave version of edge.m. I implemented a canny edge detector for my computer vision class, but haven't had time nor motivation to incorporate it into edge.m, but am more than willing to contribute my code. I also have a friend in the class who wrote a much more optimized/vectorized (yet more memory hungry) version that he said he may be willing to contribute in place of mine. John Swensen |
|
|
More New Functions: findfigs.m, isfloat.m, genvarname.mOn 10-Mar-2008, Bill Denney wrote:
| Attached are three new functions. Essentially now I'm just going | through the list of functions in matlab that are missing in octave and | writing the low hanging fruit. | # HG changeset patch | # User bill@... | # Date 1205199789 14400 | # Node ID a04d848ac6c371575205cbc130ed75035f2e9e4b | # Parent 2e72daff62ba3d194850fff4e519d23a464c45e0 | genvarname.m, isfloat.m, findfigs.m: new functions | +++ b/scripts/general/genvarname.m Mon Mar 10 21:43:09 2008 -0400 Another genvarname was just submitted. See https://www.cae.wisc.edu/pipermail/bug-octave/2008-March/005368.html | +function b = isfloat (a) | + | + b = isa (a, "double") || isa (a, "single"); I think this should probably be a built-in function, so I added it that way instead. | +function findfigs () | + | + figh = get (0, "children"); | + screensize = get (0, "monitorpositions"); Octave doesn't have a root figure property "monitorpositions". It looks like the Matlab property is "monitorposition" so at least that should be changed. Should we add this function even though it can't work until we add a functioning "monitorposition" property? | + if ((pos(1) > screensize(3)) | | + (pos(2) > screensize(4)) | | + (pos(1)+pos(3) < screensize(1)) | | + (pos(2)+pos(4) < screensize(2))) If the comparisons here are scalars, then I think this should use || instead of |. Also, there's no need for extra parens around the operands here, even though they are expressions, and the usual convention in Octave code is to put the operator first when the expressionis broken over more than one line, like this: if (pos(1) > screensize(3) || pos(2) > screensize(4) || pos(1)+pos(3) < screensize(1) || pos(2)+pos(4) < screensize(2)) Will you and Robert please reconcile your versions and submit a single function? Also, when you add new .m files, they need to be listed in the Makefile.in files where you add them. It helps if that change is included in your patch. Thanks, jwe |
|
|
Re: Q: Low hanging fruit?man, 10 03 2008 kl. 23:11 -0400, skrev John Swensen: > The image processing toolbox function 'edge' does not have a *true* > canny edge detector. There is a non-standard option called 'andy' > that is similar to the canny edge detector, but isn't quite it. That > is the only edge method still missing from the octave version of > edge.m. I implemented a canny edge detector for my computer vision > class, but haven't had time nor motivation to incorporate it into > edge.m, but am more than willing to contribute my code. I also have a > friend in the class who wrote a much more optimized/vectorized (yet > more memory hungry) version that he said he may be willing to > contribute in place of mine. contributing to the 'image' package at http://hauberg.org/share/files/edge.m I'll submit the 'canny' stuff later today. Søren |
|
|
Re: Q: Low hanging fruit?Ben Abbott wrote:
> > On Mar 10, 2008, at 9:47 PM, Bill Denney wrote: > >> Attached are three new functions. Essentially now I'm just going >> through the list of functions in matlab that are missing in octave >> and writing the low hanging fruit. >> >> Have a good day, >> >> Bill > > Bill, > > Any chance you (or anyone else) have compiled a list of "low hanging > fruit"? > > I expect there are a few individuals who would like to contribute to > that effort. > > Personally, I'd be interested in writing some m-files during my spare > time. > > Ben > aren't.. Makes it easy to find the low hanging fruit.. the dlmread/dlmwrite, etc functions should be ported from octave-forge and are already in a very good state in octave-forge itself. There are also a fair few other functions that might be ported from octave-forge and so those are the things I'd do first as the code already exists and its just a matter of coding style, texinfo help and checking for matlab compatibility. D. -- David Bateman David.Bateman@... Motorola Labs - Paris +33 1 69 35 48 04 (Ph) Parc Les Algorithmes, Commune de St Aubin +33 6 72 01 06 33 (Mob) 91193 Gif-Sur-Yvette FRANCE +33 1 69 35 77 01 (Fax) The information contained in this communication has been classified as: [x] General Business Information [ ] Motorola Internal Use Only [ ] Motorola Confidential Proprietary Function List on Matlab 2007b and which are/aren't in the core of Octave 2.9.19+. Note that the missing functions might be in Octave-Forge. In Octave abs accumarray acos acosd acosh acot acotd acoth acsc acscd acsch addpath airy all allchild amd ancestor and angle ans any area arrayfun asec asecd asech asin asind asinh assert assignin atan atan2 atand atanh axes axis balance bar barh base2dec beep besselh besseli besselj besselk bessely beta betainc betaln bin2dec bitand bitcmp bitget bitmax bitor bitset bitshift bitxor blanks blkdiag box break brighten bsxfun builtin calendar cart2pol cart2sph case cast cat catch caxis cd ceil cell cell2mat cell2struct celldisp cellfun cellstr char chol cholupdate circshift class clc clear clf clock close closereq colamd colorbar colormap colperm compass compan complex computer cond condest conj continue contour3 contour contourc contourf conv conv2 convhull convhulln copyfile corrcoef cos cosd cosh cot cotd coth cov cplxpair cputime cross csc cscd csch ctranspose cumprod cumsum cumtrapz cylinder date datenum datestr datevec dbclear dbcont dbstatus dbstep dbstop dbtype deal deblank dec2base dec2bin dec2hex deconv del2 delaunay delaunay3 delaunayn delete demo det detrend diag diary diff dir disp dmperm doc dos dot double drawnow dsearch dsearchn echo edit eig ellipj ellipke ellipsoid else elseif end eomday eps eq erf erfc erfcx erfinv erfcinv error errorbar etime etree etreeplot eval evalin exist exit exp expint expm eye ezcontour ezcontourf ezmesh ezmeshc ezplot3 ezpolar ezsurf ezsurfc factor factorial false fclose feather feof ferror feval fft fft2 fftn fftshift fftw fgetl fgets fieldnames figure fileattrib fileparts filesep fill filter filter2 find findall findobj findstr fix flipdim fliplr flipud floor flops fopen for format fplot fprintf fread fscanf fseek ftell full fullfile func2str function functions fwrite fzero gamma gammainc gammaln gca gcd gcf ge genpath get getenv getfield global gplot gradient grid griddata griddata3 griddatan gt gunzip gzip hadamard hankel help hess hex2dec hidden hist hold home horzcat hsv2rgb hypot i if ifft ifft2 ifftn ifftshift imag image imagesc ind2rgb ind2sub Inf inferiorto inline inpolygon input inputname int2str int8 int16 int32 int64 interp1 interp2 interp3 interpft interpn intersect intmax intmin inv invhilb ipermute iqr isa iscell iscellstr ischar isdir isempty isequal isequalwithequalnans isfield isfinite isglobal ishandle ishold isinf isinteger iskeyword isletter islogical ismac ismember isnan isnumeric isobject ispc isprime isreal isscalar isspace issparse isstr isstrprop isstruct isunix isvarname isvector j keyboard kron lasterr lasterror lastwarn lcm ldivide rdivide le legend legendre length license lin2mu line linspace load log log10 log2 logical loglog logm logspace lookfor lower ls lt lu luinc magic mat2cell mat2str max mean median menu mesh meshc meshgrid meshz mex mexext mfilename min mislocked mkdir mkpp mldivide mrdivide mlock mod mode more move mtimes mu2lin munlock NaN nargchk nargin nargout nchoosek ndgrid ndims ne newplot nextpow2 nnz nonzeros norm normest not now nthroot null num2cell num2str numel nzmax ones optimset or orderfields orient orth otherwise pack pareto pascal patch path pathdef pathsep pause pcg pchip pcolor peaks perms permute persistent pi pie pinv plot plotyy plot3 pol2cart polar poly polyarea polyder polyfit polyint polyval polyvalm pow2 power ppval primes prod pwd qr qrdelete qrinsert qrupdate quad quadl quit quiver quiver3 qz rand randn randperm rank rat rats real realmax realmin record rectint regexp regexpi regexprep rehash rem repmat reshape residue rethrow return rgb2hsv ribbon rmdir rmfield rmpath roots rose rosser rot90 rotate round rref run save savepath scatter scatter3 schur sec secd sech semilogx semilogy set setdiff setfield setstr setxor shading shiftdim sign sin sind single sinh size slice sort sortrows spalloc sparse spconvert spdiags speye spfun sphere sph2cart spinmap spline spones spparms sprand sprandn sprandsym sprank sprintf spy sqrt sqrtm squeeze ss2tf sscanf stairs std stem str2double str2func str2mat str2num strcat strcmp strcmpi strfind strmatch strncmp strncmpi strrep strtok strtrim struct struct2cell structfun strvcat sub2ind subplot subsasgn subsref substruct sum superiorto surf surface surfc surfnorm svd swapbytes switch symamd symbfact symrcm system tan tand tanh tar tempdir tempname text tic toc title toeplitz trace transpose trapz treeplot tril trimesh triplot triu true try tsearch tsearchn type typecast uint8 uint16 uint32 uint64 union unique unix unmkpp untar unwrap unzip upper urlread urlwrite vander var varargin varargout vectorize ver version vertcat view voronoi voronoin warning wavread wavwrite weekday what which while who whos wilkinson xlabel xlim ylabel ylim zlim zlabel xor zeros zip Missing actxcontrol actxcontrollist actxcontrolselect actxGetRunningServer actxserver addevent addframe addpref addproperty addsample addsampletocollection addtodate addts align alim alpha alphamap annotation ascii audioplayer audiorecorder aufinfo auread auwrite avifile aviinfo aviread bar3 bar3h bicg bicgstab binary builddocsearchdb bvp4c bvpget bvpinit bvpset bvpxtend calllib callSoapService camdolly cameratoolbar camlight camlookat camorbit campan campos camproj camroll camtarget camup camva camzoom cdf2rdf cdfepoch cdfinfo cdfread cdfwrite cellplot cgs checkin checkout cholinc cla clabel clipboard cmopts colmmd colordef colormapeditor comet comet3 commandhistory commandwindow condeig coneplot contourslice contrast convn copyobj createSoapMessage csvread csvwrite curl customverctrl daqread daspect datacursormode datatipinfo datetick dbdown dblquad dbmex dbquit dbstack dbup dde23 ddeadv ddeexec ddeget ddeinit ddepoke ddereq ddesd ddeset ddeterm ddeunadv debug decic deleteproperty delevent delsample delsamplefromcollection depdir depfun deval dialog diffuse display divergence dlmread dlmwrite docopt docsearch dragrect echodemo eigs enableservice errordlg evalc eventlisteners events exifread expm1 export2wsdlg ezplot figurepalette filebrowser filemarker fill3 findfigs finish fitsinfo fitsread flow fminbnd fminsearch frame2im frameedit freqspace frewind ftp funm gallery gcbf gcbo gco genvarname getabstime getappdata getdatasamplesize getframe getinterpmethod getpixelposition getpref getqualitydesc getsampleusingtime gettimeseriesnames gettsafteratevent gettsafterevent gettsatevent gettsbeforeatevent gettsbeforeevent gettsbetweenevents ginput gmres grabcode graymon gsvd gtext guidata guide guihandles hdf hdf5 hdf5info hdf5read hdf5write hdfinfo hdfread hdftool helpbrowser helpdesk helpdlg helpwin hex2num hgexport hggroup hgload hgsave hgtransform hilb histc hostid idealfilter idivide ilu im2frame im2java imfinfo imformats import importdata imread imwrite info inmem inputdlg inputParser instrcallback instrfind instrfindall inspect interfaces interp1q interpstreamspeed intwarning invoke isappdata iscom isevent isfloat isinterface isjava ismethod isocaps isocolors isonormals isosurface ispref isprop issorted isstudent javaaddpath javaArray javachk javaclasspath javaMethod javaObject javarmpath ldl libfunctions libfunctionsview libisloaded libpointer libstruct light lightangle lighting linkaxes linkprop linsolve listdlg listfonts loadlibrary loadobj log1p lscov lsqnonneg lsqr makehgtform material matlabrc matlabroot memmapfile memory methods methodsview mget minres mlint mlintrpt mmfileinfo movefile movegui movie movie2avi mput msgbox multibandread multibandwrite namelengthmax nargoutchk native2unicode noanimate notebook num2hex ode15i ode23 ode45 ode113 ode15s ode23s ode23t ode23tb odefile odeget odeset odextend open openfig opengl openvar optimget ordeig ordqz ordschur pagesetupdlg pan parseSoapResponse partialpath path2rc pathtool pbaspect pcode pdepe pdeval perl pie3 planerot playshow plotbrowser plotedit plotmatrix plottools polyeig prefdir preferences printopt printdlg printpreview profile profsave propedit propertyeditor psi publish qmr quadv questdlg rbbox rcond readasync reallog realpow realsqrt rectangle recycle reducepatch reducevolume refresh refreshdata regexptranslate registerevent release removets rename resample reset restoredefaultpath rgbplot rmappdata rmpref rotate3d rsf2csf saveas saveobj script selectmoveresize send sendmail serial serialbreak setabstime setappdata setenv setinterpmethod setpixelposition setpref settimeseriesnames showplottool shrinkfaces smooth3 sound soundsc spaugment specular start startat startup stem3 stop stopasync stream2 stream3 streamline streamparticles streamribbon streamslice streamtube strings strjust strread subsindex subspace subvolume support surf2patch surfl svds symmlq symmmd symvar synchronize syntax tetramesh texlabel textread textscan textwrap timer timerfind timerfindall timeseries todatenum toolboxdir treelayout triplequad trisurf tscollection tsdata.event tsprops tstool uibuttongroup uicontextmenu uicontrol uigetdir uigetfile uigetpref uiimport uimenu uiopen uipanel uipushtool uiputfile uiresume uiwait uisave uisetcolor uisetfont uisetpref uistack uitoggletool uitoolbar undocheckout unicode2native unloadlibrary unregisterallevents unregisterevent usejava verctrl verLessThan viewmtx volumebounds wait waitbar waitfor waitforbuttonpress warndlg waterfall wavfinfo wavplay wavrecord web whatsnew whitebg winopen winqueryreg wk1finfo wk1read wk1write workspace xlsfinfo xlsread xlswrite xmlread xmlwrite xslt zoom |
|
|
Re: Q: Low hanging fruit?On Tue, Mar 11, 2008 at 9:48 AM, David Bateman
<David.Bateman@...> wrote: > > Ben Abbott wrote: > > > > On Mar 10, 2008, at 9:47 PM, Bill Denney wrote: > > > >> Attached are three new functions. Essentially now I'm just going > >> through the list of functions in matlab that are missing in octave > >> and writing the low hanging fruit. > >> > >> Have a good day, > >> > >> Bill > > > > Bill, > > > > Any chance you (or anyone else) have compiled a list of "low hanging > > fruit"? > > > > I expect there are a few individuals who would like to contribute to > > that effort. > > > > Personally, I'd be interested in writing some m-files during my spare > > time. > > > > Ben > > > No, but I have a list of all of the functions in Matlab 2007b core and > the split between those that are implemented in Octave and those that > aren't.. Makes it easy to find the low hanging fruit.. the > dlmread/dlmwrite, etc functions should be ported from octave-forge and > are already in a very good state in octave-forge itself. There are also > a fair few other functions that might be ported from octave-forge and so > those are the things I'd do first as the code already exists and its > just a matter of coding style, texinfo help and checking for matlab > compatibility. > I've already started working on dlmread/dlmwrite. The thing is that octave-forge's dlmread is not quite like Matlab's - it cannot handle the range specification in spreadsheet format (like "A1..B10") and it cannot read the complex numbers in Matlab format <number>+<number>i. The Matlab version also appears to guess the separator from the first nonblank line, while the octave-forge version just defaults to tab or space. Moreover, I'd like dlmread to start with Matrix and allocate a ComplexMatrix only if it actually encounters a complex number (real numbers are much more common IMHO, that's why I suppose this optimization is worth it). I had my PhD exams last Friday, so I haven't done much work, but if it's a priority, I can try to finish it as fast as possible. I have not yet looked at dlmwrite - but that should be easier to deal with, especially if it can stay in m-file form. Perhaps it can even be included straight away. However, it's IMHO necessary to ensure that dlmwrite'd files can always be dlmread'ed, ideally from both Octave and Matlab. cheers, -- RNDr. Jaroslav Hajek computing expert Aeronautical Research and Test Institute (VZLU) Prague, Czech Republic url: www.highegg.matfyz.cz |
|
|
Re: Q: Low hanging fruit?Jaroslav Hajek wrote:
> I've already started working on dlmread/dlmwrite. The thing is that > octave-forge's > dlmread is not quite like Matlab's - it cannot handle the range > specification in spreadsheet format (like "A1..B10") I've added this behavior. See the attached version. > and it cannot > read the complex numbers in Matlab format > <number>+<number>i. The Matlab version also appears to guess the separator from > the first nonblank line, while the octave-forge version just defaults > to tab or space. > The fact that the separation character is inferred is apparently a recent addition. I;m not sure of a reliable means to guess this, so I'd prefer not to do it. Also Matlab's complex parsing is broken in any case and so difficult to duplicate. For example. Consider the file 1, 2, 3 4+4i, 5, 6 7, 8, 9 matlab then returns >> dlmread(file) ans = 1.0000 2.0000 3.0000 4.0000 0 + 4.0000i 5.0000 6.0000 0 0 >> dlmread(file,',') ans = 1.0000 2.0000 3.0000 4.0000 0 + 4.0000i 5.0000 6.0000 0 0 So it seems that matlab expects ALL fields to be in complex format. Note that octave-forges version reads the above correctly. Try 1i+0i, 2+0i, 3+0i 4+4i, 5+0i, 6+0i 7+0i, 8+0i, 9+0i instead. Octave-forge's version of dlmread processes this correctly. However matlab returns >> dlmread(file) ans = 0 + 1.0000i 0 2.0000 3.0000 0 0 4.0000 + 4.0000i 5.0000 6.0000 Now try adding spaces to the complex numbers 1i + 0i, 2 + 0i, 3 + 0i 4 + 4i, 5 + 0i, 6 + 0i 7 + 0i, 8 + 0i, 9 + 0i Matlab, fails to read this with >> dlmread('crud.dat') ??? Error using ==> textscan Mismatch between file and format string. Trouble reading number from file (row 1, field 2) ==> 0i, Unfortunately, my current version of dlmread current fails to read this correctly as well. How do you want to modify way dlmread works to handle complex numbers? > Moreover, I'd like dlmread to start with Matrix and allocate a > ComplexMatrix only if it > actually encounters a complex number (real numbers are much more > common IMHO, that's why I suppose this optimization is worth it). > Ok, added that as well, together with some test code for the function. Regards David -- David Bateman David.Bateman@... Motorola Labs - Paris +33 1 69 35 48 04 (Ph) Parc Les Algorithmes, Commune de St Aubin +33 6 72 01 06 33 (Mob) 91193 Gif-Sur-Yvette FRANCE +33 1 69 35 77 01 (Fax) The information contained in this communication has been classified as: [x] General Business Information [ ] Motorola Internal Use Only [ ] Motorola Confidential Proprietary /* Copyright (C) 2008 Jonathan Stickel ** Adapted from previous version of dlmread.oct as authored by Kai Habel, ** but core code has been completely re-written. ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; If not, see <http://www.gnu.org/licenses/>. */ #include "config.h" #include <fstream> #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <octave/oct.h> #include <octave/lo-ieee.h> DEFUN_DLD (dlmread, args, , "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {@var{data} =} dlmread (@var{file})\n\ @deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file},@var{sep})\n\ @deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file},@var{sep},@var{R0},@var{C0})\n\ @deftypefnx {Loadable Function} {@var{data} =} dlmread (@var{file},@var{sep},@var{range})\n\ Read the matrix @var{data} from a text file. If not defined the separator\n\ between fields is assumed to be a whitespace character. Otherwise the\n\ separation character is defined by @var{sep}.\n\ \n\ Given two scalar arguments @var{r0} and @var{c0}, these define the starting\n\ row and column of the data to be read. These values are indexed from zero,\n\ such that the first row corresponds to an index of zero.\n\ \n\ The @var{range} parameter must be a 4 element vector containing the upper\n\ left and lower right corner @code{[@var{R0},@var{C0},@var{R1},@var{C1}]} or\n\ a spreadsheet style range such as 'A2..Q15'. The lowest index value is zero.\n\ @end deftypefn") { octave_value_list retval; int nargin = args.length(); bool sepflag = 0; if (nargin < 1 || nargin > 4) { print_usage (); return retval; } if ( !args (0).is_string() ) { error ("dlmread: 1st argument must be a string"); return retval; } std::string fname (args(0).string_value()); std::ifstream file (fname.c_str()); if (!file) { error("dlmread: could not open file"); return retval; } // set default separator std::string sep; if (nargin > 1) { if (args(1).is_sq_string ()) sep = do_string_escapes (args(1).string_value()); else sep = args(1).string_value(); } //to be compatible with matlab, blank separator should correspond //to whitespace as delimter; if (!sep.length()) { sep = " \t"; sepflag = 1; } int i = 0, j = 0, r = 1, c = 1, rmax = 0, cmax = 0; std::string line; std::string str; Matrix rdata; ComplexMatrix cdata; bool iscmplx = false; size_t pos1, pos2; // take a subset if a range was given unsigned long r0 = 0, c0 = 0, r1 = ULONG_MAX-1, c1 = ULONG_MAX-1; if (nargin > 2) { if (nargin == 3) { if (args(2).is_string ()) { std::string str = args(2).string_value (); size_t n = str.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); size_t m = 0; if (n == NPOS) error ("dlmread: error parsing range"); else { c0 = 0; while (m < n) { c0 = c0 * 26; char ch = str.at (m++); if (ch >= 'a') ch -= 'a'; else ch -= 'A'; c0 += ch; } str = str.substr (n); std::istringstream tmp_stream (str); r0 = static_cast <unsigned long> (octave_read_double (tmp_stream)) - 1; str = str.substr (str.find_first_not_of("0123456789.")); n = str.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); m = 0; if (n == NPOS) error ("dlmread: error parsing range"); else { c1 = 0; while (m < n) { c1 = c1 * 26; char ch = str.at (m++); if (ch >= 'a') ch -= 'a'; else ch -= 'A'; c1 += ch; } str = str.substr (n); std::istringstream tmp_stream2 (str); r1 = static_cast <unsigned long> (octave_read_double (tmp_stream2)) - 1; } } } else { ColumnVector range(args(2).vector_value()); if (range.length() == 4) { // double --> unsigned int r0 = static_cast<unsigned long> (range(0)); c0 = static_cast<unsigned long> (range(1)); r1 = static_cast<unsigned long> (range(2)); c1 = static_cast<unsigned long> (range(3)); } else { error("dlmread: range must include [R0 C0 R1 C1]"); } } } else if (nargin == 4) { r0 = args(2).ulong_value(); c0 = args(3).ulong_value(); // if r1 and c1 are not given, use what was found to be the maximum r1 = r - 1; c1 = c - 1; } } if (!error_state) { // Skip tge r0 leading lines as these might be a header for (unsigned long m = 0; m < r0; m++) getline (file, line); // read in the data one field at a time, growing the data matrix as needed while (getline (file, line)) { // skip blank lines for compatibility if (line.find_first_not_of (" \t") == NPOS) continue; r = (r > i + 1 ? r : i + 1); j = 0; pos1 = 0; do { pos2 = line.find_first_of (sep, pos1); str = line.substr (pos1, pos2 - pos1); if (sepflag && pos2 != NPOS) // treat consecutive separators as one pos2 = line.find_first_not_of (sep, pos2) - 1; c = (c > j + 1 ? c : j + 1); if (r > rmax || c > cmax) { // use resize_and_fill for the case of not-equal length rows if (iscmplx) cdata.resize_and_fill (r, c, 0); else rdata.resize_and_fill (r, c, 0); rmax = r; cmax = c; } std::istringstream tmp_stream (str); double x = octave_read_double (tmp_stream); if (tmp_stream) { if (tmp_stream.eof()) if (iscmplx) cdata (i, j++) = x; else rdata (i, j++) = x; else { double y = octave_read_double (tmp_stream); if (!iscmplx && y != 0.) { iscmplx = true; cdata = ComplexMatrix (rdata); } if (iscmplx) cdata (i, j++) = Complex (x, y); else rdata (i, j++) = x; } } else if (iscmplx) cdata (i, j++) = 0.; else rdata (i, j++) = 0.; if (pos2 != NPOS) pos1 = pos2 + 1; else pos1 = NPOS; } while ( pos1 != NPOS ); i++; } if (nargin > 2) { if (nargin == 3) { if (r1 >= r) r1 = r - 1; if (c1 >= c) c1 = c - 1; } else if (nargin == 4) { // if r1 and c1 are not given, use what was found to be the maximum r1 = r - 1; c1 = c - 1; } // now take the subset of the matrix if (iscmplx) { cdata = cdata.extract (0, c0, r1, c1); cdata.resize (r1 + 1, c1 - c0 + 1); } else { rdata = rdata.extract (0, c0, r1, c1); rdata.resize (r1 + 1, c1 - c0 + 1); } } if (iscmplx) retval(0) = octave_value(cdata); else retval(0) = octave_value(rdata); } return retval; } /* %!shared file %! file = tmpnam (); %! fid = fopen (file, "wt"); %! fwrite (fid, "1, 2, 3\n4, 5, 6\n7, 8, 9"); %! fclose (fid); %!assert (dlmread (file), [1, 2, 3; 4, 5, 6; 7, 8, 9]); %!assert (dlmread (file, ","), [1, 2, 3; 4, 5, 6; 7, 8, 9]); %!assert (dlmread (file, ",", [1, 0, 2, 1]), [4, 5; 7, 8]); %!assert (dlmread (file, ",", "B1..C2"), [2, 3; 5, 6]); %!test %! unlink (file); %!shared file %! file = tmpnam (); %! fid = fopen (file, "wt"); %! fwrite (fid, "1, 2, 3\n4+4i, 5, 6\n7, 8, 9"); %! fclose (fid); %!assert (dlmread (file), [1, 2, 3; 4 + 4i, 5, 6; 7, 8, 9]); %!assert (dlmread (file, ","), [1, 2, 3; 4 + 4i, 5, 6; 7, 8, 9]); %!assert (dlmread (file, ",", [1, 0, 2, 1]), [4 + 4i, 5; 7, 8]); %!assert (dlmread (file, ",", "A2..B3"), [4 + 4i, 5; 7, 8]); %!test %! unlink (file); */ |
|
|
Re: Q: Low hanging fruit?On Tue, Mar 11, 2008 at 3:10 PM, David Bateman
<David.Bateman@...> wrote: > Jaroslav Hajek wrote: > > I've already started working on dlmread/dlmwrite. The thing is that > > octave-forge's > > dlmread is not quite like Matlab's - it cannot handle the range > > specification in spreadsheet format (like "A1..B10") > I've added this behavior. See the attached version. > OK. Just for fun, I ended up with this (untested): static bool read_cell_spec(std::istream& is, octave_idx_type& row, octave_idx_type& col) { bool stat; octave_idx_type c; if (is && isalpha (is.peek ())) { col = toupper (is.get ()) - 'A'; if (isalpha (is.peek ())) col = 26*(col + 1) + toupper(is.get ()) - 'A'; is >> row; } return is && is.eof () || (c = is.get (), c == '.' && is.get () == '.' || c == ':'); } static bool parse_range_spec(const octave_value& range_spec, octave_idx_type& rlo, octave_idx_type& clo, octave_idx_type& rup, octave_idx_type& cup) { if (range_spec.is_real_matrix () && range_spec.numel () == 4) { Matrix m = range_spec.matrix_value (); rlo = m(0); clo = m(1); rup = m(2); cup = m(3); return true; } else if (range_spec.is_string ()) { std::istringstream sps (spstr); return read_cell_spec (sps, rlo, clo) && read_cell_spec (sps, rup, cup); } else return false; } so that you can specify "A1..B10", "A1:B10", ":B10", "A1:" or "A1.." > > > and it cannot > > read the complex numbers in Matlab format > > <number>+<number>i. The Matlab version also appears to guess the separator from > > the first nonblank line, while the octave-forge version just defaults > > to tab or space. > > > The fact that the separation character is inferred is apparently a > recent addition. I;m not sure of a reliable means to guess this, so I'd > prefer not to do it. Also Matlab's complex parsing is broken in any case > and so difficult to duplicate. For example. Consider the file > > 1, 2, 3 > 4+4i, 5, 6 > 7, 8, 9 > > matlab then returns > > >> dlmread(file) > ans = > > 1.0000 2.0000 3.0000 > 4.0000 0 + 4.0000i 5.0000 > 6.0000 0 0 > > >> dlmread(file,',') > > ans = > > 1.0000 2.0000 3.0000 > 4.0000 0 + 4.0000i 5.0000 > 6.0000 0 0 > > So it seems that matlab expects ALL fields to be in complex format. Note > that octave-forges version reads the above correctly. Try > > 1i+0i, 2+0i, 3+0i > 4+4i, 5+0i, 6+0i > 7+0i, 8+0i, 9+0i > > instead. Octave-forge's version of dlmread processes this correctly. > However matlab returns > > >> dlmread(file) > > ans = > > 0 + 1.0000i 0 2.0000 > 3.0000 0 0 > 4.0000 + 4.0000i 5.0000 6.0000 > > Now try adding spaces to the complex numbers > > 1i + 0i, 2 + 0i, 3 + 0i > 4 + 4i, 5 + 0i, 6 + 0i > 7 + 0i, 8 + 0i, 9 + 0i > > Matlab, fails to read this with > > >> dlmread('crud.dat') > ??? Error using ==> textscan > Mismatch between file and format string. > Trouble reading number from file (row 1, field 2) ==> 0i, > > Unfortunately, my current version of dlmread current fails to read this > correctly as well. How do you want to modify way dlmread works to handle > complex numbers? > OK, I don't think this has to be pushed too far. There are more ways how to write a complex number (thinking of the Fortran (a,b) style), and there's no need for dlmread to be too smart, I think that basically it's enough if it can read whatever written with dlmwrite or save. > > > Moreover, I'd like dlmread to start with Matrix and allocate a > > ComplexMatrix only if it > > actually encounters a complex number (real numbers are much more > > common IMHO, that's why I suppose this optimization is worth it). > > > Ok, added that as well, together with some test code for the function. > Cool. It seems I can give up with my work on this. But one more suggestion: It seems that your version reads more than is needed and then strip the result. I would consider it more sound not to grow the matrix more than needed, at least row-wise, as there may be much more data in the file than actually needed. If always the whole file was read and then the result stripped, the range parameter would actually be unnecessary as you can achieve the same by slicing after the reading. cheers, -- RNDr. Jaroslav Hajek computing expert Aeronautical Research and Test Institute (VZLU) Prague, Czech Republic url: www.highegg.matfyz.cz |
|
|
Re: Q: Low hanging fruit?On 11-Mar-2008, David Bateman wrote:
| Ok, added that as well, together with some test code for the function. Please send dlmread/dlmwrite as hg changesets when the |