MATLAB Examples

tprintf writes tabular data to a text file

tprintf provides a more intuitive interface to fprintf for writing tabular data to a text file. tprintf(filespec,format,A1,...,An) creates a tabular text file by writing the columns of A1,...,An to columns in the text file.

Contents

Background

Design goals

  • its interface shall be easy to grasp and remember
  • its interface shall be close to that of fprintf
  • it shall require a minimum of code in the calling function
  • it shall be fast

fprintf( fid, format, v1,v2, ... ), where v1,v2,... are scalars, writes one row. To print several rows one may put the function in a for-loop. That code is easy to read and understand. However, with large files speed becomes a problem. fprintf(...,C{:}), where C is a cell array containing numeric and character data, writes the text file much faster. With pure numerical data fprintf(...,M), where M is matrix writes even faster. However, the cell array, C, and the matrix, M, come at a price. It takes some effort to create them and the resulting code is not all that easy to read and understand - IMO. With tprintf I try to combined the best of the two.

Installation

This submission consists of three m-files and this documentation. Copy the m-files to a folder on the Matlab search path.

Examples

These examples show different uses of tprintf. Browsing through them gives a good notion of the capability of tprintf.

Sample data: Create column oriented data of different kinds. All data variables have five rows to keep the printed files small.

N   = 5;
ffs = 'c:\tmp\tprintf.txt';

f1  = rand( N, 1 );
f2  = rand( N, 2 ) * 2;
f3  = rand( N, 3 ) * 3;

i1  = ones( N, 1, 'int8' );
i2  = ones( N, 2, 'int8' ) * 2;
i3  = ones( N, 3, 'int8' ) * 3;

cs1 = {'ABC';'DEF';'GHI';'JKL';'MNO'};
s1  = ['MNO';'PQR';'STU';'VWX';'YZZ'];
cs2 = cat( 2, cs1, lower(cs1) );

whos f1 f2 f3 i1 i2 i3 cs1 cs2 s1
  Name      Size            Bytes  Class     Attributes

  cs1       5x1               590  cell                
  cs2       5x2              1180  cell                
  f1        5x1                40  double              
  f2        5x2                80  double              
  f3        5x3               120  double              
  i1        5x1                 5  int8                
  i2        5x2                10  int8                
  i3        5x3                15  int8                
  s1        5x3                30  char                

Formatted double

tprintf( ffs, '%6.3f,%6.3f,%6.3f,%6.1f,%6.2f,%6.2f\n', f3, f1, f2 );
type( ffs )
 0.381, 0.631, 2.506,   0.6,  1.94,  1.77
 2.405, 0.887, 1.134,   0.1,  1.54,  1.43
 0.316, 0.454, 2.452,   0.1,  0.43,  0.01
 0.885, 0.332, 0.707,   0.7,  0.84,  1.12
 0.008, 0.802, 2.801,   0.6,  1.94,  1.29

Integers

tprintf( ffs, '%d,%d,%d,%d,%d,%d\n', i3, i1, i2 );
type( ffs )
3,3,3,1,2,2
3,3,3,1,2,2
3,3,3,1,2,2
3,3,3,1,2,2
3,3,3,1,2,2

Strings

tprintf( ffs, '%s,%s,%s,%s\n', cs2, cs1, s1 );
type( ffs )
ABC,abc,ABC,MNO
DEF,def,DEF,PQR
GHI,ghi,GHI,STU
JKL,jkl,JKL,VWX
MNO,mno,MNO,YZZ

Combination of the classes with an extra space between the columns

tprintf( ffs, '%s, %d, %s, %f, %f, %f, %s, %s\n', cs1, i1, s1, f3, cs2 );
type( ffs )
ABC, 1, MNO, 0.380620, 0.630681, 2.505789, ABC, abc
DEF, 1, PQR, 2.404988, 0.886882, 1.133766, DEF, def
GHI, 1, STU, 0.315689, 0.454042, 2.451792, GHI, ghi
JKL, 1, VWX, 0.884717, 0.331564, 0.706787, JKL, jkl
MNO, 1, YZZ, 0.007668, 0.801814, 2.800864, MNO, mno

And with a header row.

delete( ffs )
fid = fopen( ffs, 'a' );
fprintf( fid, '%s\n', 'Col1, Col2, Col3, Col4, Col5, Col6' );
tprintf( fid, '%s, %d, %s, %f, %f, %f\n', cs1, i1, s1, f3 );
fclose( fid );
type( ffs )
Col1, Col2, Col3, Col4, Col5, Col6
ABC, 1, MNO, 0.380620, 0.630681, 2.505789
DEF, 1, PQR, 2.404988, 0.886882, 1.133766
GHI, 1, STU, 0.315689, 0.454042, 2.451792
JKL, 1, VWX, 0.884717, 0.331564, 0.706787
MNO, 1, YZZ, 0.007668, 0.801814, 2.800864

Comarison of speed between tprintf, csvwrite, save(...,'-ascii') and for,fprintf,end

The results below indicate that tprintf and save(...,'-ascii') are an order of magnitude faster than, csvwrite and for,fprintf,end.

warning( 'off', 'MATLAB:DELETE:FileNotFound')
N = 1e5;
ffs = 'c:\tmp\tprintf.txt';
num = rand( N, 6 );
n1 = num(:,1);  n2 = num(:,2);  n3 = num(:,3);
n4 = num(:,4);  n5 = num(:,5);  n6 = num(:,6);

fprintf( '\ntprintf\n' );
delete( ffs )
tic
tprintf( ffs, '%f,%f,%f,%f,%f,%f\n', n1,n2,n3,n4,n5,n6 );
toc
fid = fopen( ffs );
tpr = textscan( fid, '%f%f%f%f%f%f', 'Delimiter',',', 'CollectOutput',true );
tpr = tpr{1};
fclose( fid );
max(abs(tpr-num))

fprintf( '\ncsvwrite\n' );
delete( 'c:\tmp\tprintf.csv' )
tic
csvwrite( 'c:\tmp\tprintf.csv', num );
toc
csv = csvread( 'c:\tmp\tprintf.csv' );
max(abs(csv-num))

fprintf( '\nsave\n' );
delete( 'c:\tmp\tprintf.mat' )
tic
save( 'c:\tmp\tprintf.mat', 'num', '-ASCII' );
toc
msl = load( 'c:\tmp\tprintf.mat', '-ASCII' );
max(abs(msl-num))

fprintf('\nfor,fprintf,end\n');
delete('c:\tmp\loop_fprintf.txt')
tic
fid = fopen('c:\tmp\loop_fprintf.txt','W');
for jj = 1 : N
    fprintf( fid, '%f,%f,%f,%f,%f,%f\n' ...
        ,   n1(jj,:),n2(jj,:),n3(jj,:),n4(jj,:),n5(jj,:),n6(jj,:) );
end
fclose( fid );
toc
fid = fopen('c:\tmp\loop_fprintf.txt');
ffe = textscan( fid, '%f%f%f%f%f%f', 'Delimiter',',', 'CollectOutput',true );
ffe = ffe{1};
fclose( fid );
max(abs(ffe-num))
warning( 'on', 'MATLAB:DELETE:FileNotFound')
tprintf
Elapsed time is 0.592410 seconds.
ans =
   1.0e-06 *
    0.5000    0.5000    0.5000    0.5000    0.5000    0.5000

csvwrite
Elapsed time is 5.012890 seconds.
ans =
   1.0e-05 *
    0.5000    0.5000    0.5000    0.5000    0.5000    0.5000

save
Elapsed time is 0.508718 seconds.
ans =
   1.0e-08 *
    0.5000    0.5000    0.5000    0.5000    0.5000    0.5000

for,fprintf,end
Elapsed time is 3.999473 seconds.
ans =
   1.0e-06 *
    0.5000    0.5000    0.5000    0.5000    0.5000    0.5000