function save4(varargin) % save4 -- Versatile "save", using Matlab v4 Mat-file. % save4('demo') exercizes itself with "save4(10)". % save4(N) exercizes itself with N-by-N random data. % save4('filename') saves all compatible variables % to "filename". Default filename = 'matlab.mat'; % default extension = '.mat'. % save4('filename', 'var1', 'var2', ..., '-precision', ... % '-asis', '-append') saves the given variables % (double, char, and sparse arrays) in a Matlab v4 % Mat-file, using the specified precision, plus % other options: % % '-double' Default for numbers. % '-single' % '-long' % '-short' % '-ushort' Default for strings. % '-uchar' % % '-asis' Store integers without packing. % '-append' Append variables to existing file. % % Note: Multi-dimensional arrays are cast to two-dimensions. % Note: Experience with NaN and Inf as integers may vary. % % Also see: SAVE, LOAD. % Copyright (C) 2002 Dr. Charles R. Denham, ZYDECO. % All Rights Reserved. % Disclosure without explicit written consent from the % copyright owner does not constitute publication. % Version of 17-Jan-2002 09:49:50. % Updated 18-Jan-2002 11:45:34. % Demonstration. if length(varargin) == 1 & isequal(varargin{1}, 'demo') help(mfilename) varargin{1} = 10; end if length(varargin) == 1 & any(varargin{1}(1) == '01234567890+-.') varargin{1} = eval(varargin{1}); end if length(varargin) == 1 & isequal(class(varargin{1}), 'double') n = max(round(varargin{1}), 1); x = rand(n, n); y = x; y(y < 0.5) = 0; y = sparse(y); z = fix(x * 100); c = char(z); xx = x; yy = y; zz = z; cc = c; filename = [mfilename '_demo.mat']; disp([' ## Using Mat-file "' filename '".']) feval(mfilename, filename, 'x', 'y') feval(mfilename, filename, 'z', 'c', '-append') clear x y z c load(filename) s = [' ## ' mfilename '(' int2str(n) '): Round-trip']; if isequal(x, xx) & isequal(y, yy) & ... isequal(z, zz) & isequal(c, cc) disp([s ' succeeded.']) else disp([s ' failed.']) end return end % Adjust calling arguments. if nargin < 1 varargin = {'matlab.mat'}; end count = length(varargin); for i = 1:length(varargin) var = varargin{i}; if var(1) == '-' count = count - 1; end end if count < 2 w = evalin('caller', 'whos'); w = {w.name}; w = w(:).'; varargin = [varargin w]; end % Default settings. doAppend = 0; doAsis = 0; thePrecision = 'float64'; % Default M O P T code. M = 1; % Machine: IEEE Big-endian. O = 0; % Always zero. P = 0; % Precision: see below. T = 0; % Type of data: matrix (0), string (1), or sparse (2) % Interpret the precision and other options. for i = 2:length(varargin) var = varargin{i}; if var(1) == '-' switch lower(var) case {'-double', '-float64'} thePrecision = 'float64'; P = 0; case {'-single', '-float', '-float32'} thePrecision = 'float32'; P = 1; case {'-long', '-slong', '-int32'} thePrecision = 'int32'; P = 2; case {'-short', '-sshort', '-int16'} thePrecision = 'int16'; P = 3; case {'-ushort', '-uint16'} thePrecision = 'uint16'; P = 4; case {'-uchar', '-ubyte', '-uint8'} thePrecision = 'uint8'; P = 5; case '-append' doAppend = 1; case '-asis' doAsis = 1; otherwise disp([' ## Unknown thePrecision: ' var]) return end end end % Default to ".mat" extension if none given. theFilename = varargin{1}; if ~any(theFilename == '.') theFilename = [theFilename '.mat']; end % Open the file in native format. if doAppend fid = fopen(theFilename, 'a', 'native'); else fid = fopen(theFilename, 'w', 'native'); end if fid < 0 disp([' ## ' mfilename ': Unable to open file: ' theFilename]) return end % Code for machine-format. [filename, permission, machineformat] = fopen(fid); switch machineformat case 'ieee-le' M = 0; case 'ieee-be' M = 1; case 'vaxd' M = 2; case 'vaxg' M = 3; case 'cray' M = 4; otherwise disp([' ## Incompatible machine-format. Nothing saved.']) fclose(fid) return end % Save compatible variables. for i = 2:length(varargin) var = varargin{i}; if var(1) ~= '-' try w = evalin('caller', ['which(''' var ''')']); c = evalin('caller', ['class(' var ')']); if ~(isequal(w, 'variable') & ... (isequal(c, 'char') | ... isequal(c, 'double') | ... isequal(c, 'sparse'))) disp(' ') disp([' ## ' mfilename ': Not a compatible type.']) disp([' ## Unable to save "' var '".']) else x = evalin('caller', var); sz = size(x); if length(sz) > 2 % Force to 2-d. sz = [sz(1) prod(sz(2:end))]; x = reshape(x, sz); end switch class(x) case 'double' T = 0; % Type = full-matrix. prec = thePrecision; case 'char' % Might be 16-bit Unicode. T = 1; % Type = string. P = 4; % Unsigned short integer. prec = 'uint16'; % As in Matlab v5+. case 'sparse' T = 2; % Type = sparse. prec = thePrecision; [row, col, val] = find(x); row = [row(:); sz(1)]; col = [col(:); sz(2)]; val = [val(:); 0]; x = [row col val]; sz = size(x); end if ~doAsis % Pack if all integer. y = x(:); if all(isfinite(y)) if ~isreal(y) y = [real(y); imag(y)]; end if ~any(rem(y, 1)) mn = min(y); mx = max(y); if mn >= 0 & mx < 2^8 % Unsigned byte. P = 5; prec = 'uint8'; elseif mn >= 0 & mx < 2^16 % Unsigned short. P = 4; prec = 'uint16'; elseif mn >= -2^15 & mx < 2^15 % Signed short. P = 3; prec = 'int16'; elseif mn >= -2^31 & mx < 2^31 % Signed long. P = 2; prec = 'int32'; end end end end MOPT = 1000*M + 100*O + 10*P + T; mrows = sz(1); ncols = sz(2); imagflag = abs(~isreal(x)); namelen = length(var) + 1; % Includes null-byte. name = var; null = 0; fwrite(fid, [MOPT mrows ncols imagflag namelen], 'uint32'); fwrite(fid, name, 'uint8'); fwrite(fid, 0, 'uint8'); % Null-byte. if imagflag fwrite(fid, real(x), prec); fwrite(fid, imag(x), prec); else fwrite(fid, x, prec); end end catch disp(' ') disp([' ## ' mfilename ': Error = "' lasterr '"']) disp([' ## Unable to save "' varargin{i} '".']) end end end % Close and return. fclose(fid);