Wednesday, March 28, 2012

Writing multiple column vectors to file in Matlab and Octave

Consider a simple example. If x and y are two vectors of the same size, one obvious way of writing them to file is:

n  = 1e5;
x  = 1:n;
y  = x.^2;
f1 = fopen('xy.dat','w');
for i = 1:length(x)
    fprintf(f1,'%d\t%d\n',x(i),y(i));
end
fclose(f1);

[Side Note: Matlab does not have a command like Octave's "printf" - if "fprintf" is used without a file handle, then it outputs to the screen.]

I ran timings for the "red" writing part of the code above in Matlab 7.4 R2011b and Octave 3.4.2 on my Desktop, and found that it took 3.4s and 2.6s, respectively. It isn't usual for Octave to outrun Matlab, but this may have something to do with the peculiarities of my installation.

I replaced the "for-loop" in the write operation with a single command:

fprintf(f1,'%d\t%d\n',x,y);

and my timings improved. It took 0.13s and 0.11s for Matlab and Octave, respectively. So clearly getting rid of the for loop helps (no surprise!).

Sometimes, you may be in a hurry and not care so much for the control over formatting that fprintf offers. If you want avoid all the fopen and fclose business, you could instead use, something like:

xy = [x' y'];
save('xy.dat', 'xy','-ascii');

Note that I need to define a "matrix", with the columns side by side to use this.  It took 0.23s and 0.28s for Matlab and Octave, respectively - so there is a small performance hit.

2 comments:

Anonymous said...

The loop version gives this:
1 1
2 4
3 9
4 16
...
But, at least in Octave, the second gives this result instead:
1 2
3 4
5 6
7 8
9 10
11 12
This is not the same!

Sachin Shanbhag said...

You are right, I get the same result with Octave 3.6.2. A dirty hack to get the expected result is:

printf("%d\t%d\n",[x;y])