More New Functions: findfigs.m, isfloat.m, genvarname.m

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 - 3 | Next >

More New Functions: findfigs.m, isfloat.m, genvarname.m

by Bill Denney-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

# 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?

by Ben Abbott :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


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?

by John Swensen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


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.m

by John W. Eaton :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 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?

by Søren Hauberg :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


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.
I have a fairly good implementation of 'edge' that I never got around to
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?

by David Bateman :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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.

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
print
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?

by Jaroslav Hajek-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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?

by David Bateman :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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?

by Jaroslav Hajek-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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?

by John W. Eaton :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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