From bug-octave-request at bevo dot che dot wisc dot edu Wed Jan 1 12:38:34 2003 Subject: RE: Bugs with strings, fread function From: "Dr. Julian A. de Marchi" To: "James Frye" , Date: Wed, 1 Jan 2003 13:41:11 -0500 OK, this is interesting. (Nothing like a good brain teaser for the new year!) First, James, I looked at your scripts and what jumped out at me straight away was that parsearg.m indexes the argument elements by way of curly brackets {}, rather than parentheses (). This indicates that the script is expecting a cell array of elements. So, I first looked up nargin and varargin in Windows Octave/Forge 2.1.36 and found that there is no man page for there (first problem). But they do exist in Octave (good news). Next I ran a simple script: function test(varargin); varargin, iscell(varargin), isstr(varargin) And indeed Matlab (I used R11.1) (for which your script is native and works) report varargin as a cell array, which makes sense in the context of how your script is trying to work with it: [Matlab] > test varargin = {} ans = 1 ans = 0 The curly brackets say that varargin is a cell array. ans=1 confirms this. ans=0 to follow doubly confirms this. However, running the same "test" in Octave: [Octave] >> test error: `varargin' undefined near line 3 column 1 error: called from `test' in file `/octave_files/test.m' Oops -- test with zero arguments does not generate an empty cell array varargin! This is the first incompatibility. So next I tried [Matlab] > test('fname', 'tst.bin') varargin = 'fname' 'tst.bin' ans = 1 ans = 0 and [Octave] >> test('fname', 'tst.bin') varargin = fname ans = 0 ans = 1 So it seems all this information put together suggests that Octave casts varargin as a string array of characters rather than a cell array of strings. This is the reason you see length(args) = 5 in your script when running under Octave. Because length(a string) will return the number of characters in the string whereas length(a cell array) returns the number of elements in the cell array. I tried the above "tests" using numeric data as well as string data and the same incompatibility arises. Under Matlab: > help varargin VARARGIN Variable length input argument list. Allows any number of arguments to a function. The variable VARARGIN is a cell array containing the optional arguments to the function. VARARGIN must be declared as the last input argument and collects all the inputs from that point onwards. In the declaration, VARARGIN must be lowercase (i.e., varargin). For example, the function, function myplot(x,varargin) plot(x,varargin{:}) collects all the inputs starting with the second input into the variable "varargin". MYPLOT uses the comma-separated list syntax varargin{:} to pass the optional parameters to plot. The call, myplot(sin(0:.1:1),'color',[.5 .7 .3],'linestyle',':') results in varargin being a 1-by-4 cell array containing the values 'color', [.5 .7 .3], 'linestyle', and ':'. See also VARARGOUT, NARGIN, NARGOUT, INPUTNAME, FUNCTION, LISTS. My naive guess is that perhaps the version of Octave you are using (and I myself) eitehr does not support varargin, or, there is a compiler flag with which our versions would need to be rebuilt to support the cell array functionality. Finally I tried to help Octave out a little by explicitly casting the arguments as cell arrays, with positive result: [Octave] >> test({'fname', 'tst.bin'}) nargin = 1 varargin = { [1,1] = fname [1,2] = tst.bin } ans = 1 ans = 0 However, unfortunately, there seems to be a problem in (my version of) Octave with regard to taking the length() of a cell array, which may be at the root of the problem running your script: [Octave] >> x={'fname', 'tst.bin'}, length(x) x = { [1,1] = fname [1,2] = tst.bin } ans = -1 whereas in Matlab [Matlab] > x={'fname', 'tst.bin'}, length(x) x = 'fname' 'tst.bin' ans = 2 I suspect this will be enough info for someone to help you resolve the issue. It's a good thing you included your sources this time because without them your previous emails have been very confusing! This helps a lot! By the way you have the keyword "end" closing your function tst.m which in Matlab is a bug. Recent changes by JWE make this also superfluous in Octave, so best remove it. Cheers & Happy New Year! - Julian / MatLinks -----Original Message----- From: James Frye [mailto:frye at cs dot unr dot edu] Sent: Tuesday, 31 December 2002 16.55 To: bug-octave at bevo dot che dot wisc dot edu Subject: Bugs with strings, fread function Problem with string arguments; Problem with fread function. The attached files demonstrate two cases where octave does not appear compatible with Matlab. It is cut down from one of our actual scripts. The string problem may just be a case of octave having a different syntax (if so, I'd like to know what it is), but the fread problem seems to be a real bug. The script is called as function tst. The arguments are passed to function parsearg, where they are scanned as keyword:value pairs. Thus giving octave the command tst ('fname', 'tst.bin'); should pass the arguments to parseargs, which should see the keyword "fname", and assign the string "tst.bin" to the variable fname. This works in Matlab. In octave, the line nargs = length (args); returns nargs = 5 (or whatever the length of the first argument string to tst was). If one prints out the values of "args{a}", they are 'f', 'n', 'a', 'm', 'e'. In other words, it appears that octave is somehow separating the string "fname" into its individual characters. The second error (or perhaps several related errors) will appear if you comment out the call to parsearg, and simply set fname = 'tst.bin'. It will apparently read the strings (the freads using 'uchar') from the file, but does not assign or print them correctly. It appears to read 'int32' values correctly, but when it tries to read 'float32' values, it stops with an 'invalid size specification' error message. The script does work with the Windows version of Matlab (6.0.0.88 (R12)). Here's configuration information. I can't use the octave bug_report function, since the machines I have octave on don't allow outgoing (or incoming) mail. Octave version 2.1.34 (It does much the same on the 2.1.50? version that I compiled from the CVS sources on my home machine. Script and input file are attached. Call with above args. Machine is dual CPU PIII, 1 GHz. OS is Linux version 2.4.9-31smp (bhcompile at daffy dot perf dot redhat dot com) (gcc version 2.96 20000731 (Red Hat Linux 7.1 2.96-98)) #1 SMP Tue Feb 26 06:55:00 EST 2002 I don't know the configure args, as it was intstalled by our sysop. I believe from a package, but I'm not sure. I have made no modifications to the source. Files in attached .tgz file: read.me - this text tst.m - main .m file parsearg.m - function to be called from tst.m tst.bin - a sample input file to be read by tst.m ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------