物探论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1060|回复: 0

[算法] 按指定格式保存数据

[复制链接]
发表于 2013-11-25 21:47:44 | 显示全部楼层 |阅读模式
1.png
function [X,FULLFMT] = saveascii(X,varargin)
%SAVEASCII   Save/display a matrix with specific format for each column.
%
%   SYNTAX:
%                   saveascii(X)                 % Displays
%                   saveascii(X,...,FMT)
%                   saveascii(X,...,DLM)
%                   saveascii(X,FILE,...)        % Saves
%                   saveascii(X,FILE,...,'a')    % Appends
%     [Y,FULLFMT] = saveascii(...);
%
%   INPUT:
%     X    - 2-dimensional numeric, logical or string array with Ncol
%            columns to be saved/display, with/without NaNs, or a vector of
%            cell of strings.
%     DLM  - One or Ncol-1 strings on a cell specifying the delimiter(s)
%            between every/each pair if columns.
%            DEFAULT: {' '} or {''} (the latter if X is char)
%     FMT  - One or Ncol integers in a vector specifying the PRECISION for
%            every/each column, or One or Ncol strings in a cell specifying
%            its format(s). See NOTE below.
%            DEFAULT: '% 8.7e' or '%c' (the latter if X is char)
%     FILE - File name or identifier specifying the output file.
%            DEFAULT: not used (just displays)
%     'a'  - Appends to the given FILE in text mode. Use 'w -i' to active a
%            OVERWRITE warning. See NOTE below.
%            DEFAULT: 'w' (creates/OVERWRITES! the given FILE in text mode)
%
%   OUTPUT (all optional):
%     Y       - Matrix X converted to a string with specified format(s) and
%               delimiter(s).
%     FULLFMT - Format used to save/dislay the matrix. If X is a cell of
%               strings, this is also a cell of strings without the End of
%               Line.
%
%   DESCRIPTION:
%     This program saves/displays a matrix array by using SPRINTF/FPRINTF
%     with specific format (FMT) and delimiter (DLM) for every or EACH
%     column in a very handy way, which is the mayor difference with SAVE
%     or DLMWRITE function.
%
%     The point of this program is to allow the user to save/display any
%     numeric or char matrix as easy as posible without messing with the
%     appropiate format ('%...') to do it, only with the precision (if is
%     numerical). See the EXAMPLE below.
%
%   NOTE:
%     * Optional inputs use its DEFAULT value when not given or [].
%     * Optional outputs may or not be called.
%     * FMT and DLM may be a single string.
%     * When FMT is used as precision integers, negative ones indicates to
%       treat column(s) of X as integers rounded up to those significant
%       digits to the left!
%     * ADDITIONAL NOTES are included inside this file.
%
%   EXAMPLE:
%     x = [    1    2    pi
%              4  NaN     6
%           75.4  Inf   8.5 ];
%     % Display with 3 significant decimals.
%       saveascii(x,3)
%         % RETURNS:
%         %  1.000  2.000  3.142
%         %  4.000    NaN  6.000
%         % 75.400    Inf  8.500
%         %
%     % Display with specific significant decimals.
%       saveascii(x,[-1 2 0])
%         % RETURNS:
%         %  0 2.00 3
%         %  0  NaN 6
%         % 80  Inf 9
%         %
%     % Displays with ' hello ' and ' bye ' as delimiter.
%       saveascii(x,{' hello ',' bye '},2)
%         % RETURNS:
%         %  1.00 hello  2.00 bye  3.14
%         %  4.00 hello   NaN bye  6.00
%         % 75.40 hello   Inf bye  8.50
%         %
%     % Saves on 'saveascii_demo.txt' with heading.
%       FILE = 'saveascii_demo.txt';
%       saveascii('% Demo file'                   ,FILE)
%       saveascii(['%  Pi = ' saveascii(pi,3) ';'],FILE,'a')
%       saveascii(x                               ,FILE,'a',0)
%       edit(FILE)
%       demo = load(FILE)
%         % RETURNS:
%         % demo =
%         %
%         %      4   NaN     6
%         %     75   Inf     9
%         %
%     % NOTE: see how the heading is ignored by the LOAD function.
%        
%   SEE ALSO:
%     SAVE, FPRINTF, SPRINTF, DLMWRITE, CSVWRITE, FOPEN, STR2DOUBLE,
%     STR2NUM, NUM2STR

%   DISCLAIMER:
%   saveascii.m is provided "as is" without warranty of any kind, under the
%   revised BSD license.

%   Copyright (c) 2004,2006,2007,2008,2009 Carlos Adrian Vargas Aguilera


% INPUTS CHECK-IN
% -------------------------------------------------------------------------

% Checks number of inputs and outputs.
if     nargin<1
error('CVARGAS:saveascii:notEnoughInputs',...
  'At least 1 input is required.')
elseif nargin>5
error('CVARGAS:saveascii:tooManyInputs',...
  'At most 5 inputs are allowed.')
elseif nargout>2
error('CVARGAS:saveascii:tooManyOutputs',...
  'At most 2 outputs are allowed.')
end

% Sets defaults:
FILE = [];          % Function mode:
                    %              [] : display
                    %    filename/fid : save
PER  = 'w';         % Open permission:
                    %    'w' : OVERWRITES without warning
                    %    'a' : ppends
TOB  = 't';         % Write mode:
                    %    't' : text
                    %    'b' : binary (FOPEN default)
WAR  = false;       % Overwrite warning:
                    %    false : do not warns
                    %    true  : do warns
if ischar(X) ||...  % String matrix
  iscellstr(X)      % or cell of strings input:
FMT = {'%c'};      %    Format string for each (every) column.
DLM = {''};        %    If just text, nothing between chars.
else                % Numeric (real) or logical matrix input:
FMT = {'% 8.7e'};  %    Ugly, but MATLAB seems to like it, do you?
DLM = {' '};       %    Single space. Try '\t' (tab).
end                 %
BOEL  = '';         % String at the Begining of Each line.
EOEL  = '\n';       % String at the End Of Each Line
                    %    '\n' : for Windows and Unix OS users
                    %    '\r' : for Mac OS users (I guess, not tested)
PRE  = [];          % Not used by default.
WID  = [];          % Not used by default.
SPC  = 'f';         % Floating-point specifier.


% CHECKS X ================================================================
% Checks X size.
Nrow = size(X);
if length(Nrow)>2
error('CVARGAS:saveascii:incorrectXDimension',...
  'X must be a 2-dimensional matrix array.')
else
Ncol = Nrow(2);
Nrow = Nrow(1);
end
% Checks X empty, type and complex.
Xemp  = isempty(X);
Xnum  = false;
Xcell = false;
if ~Xemp && (isnumeric(X) || islogical(X)) % Fixed BUG (May 07, 2009)
if ~isreal(X)
  warning('CVARGAS:saveacii:complexInput',...
  'Imaginary parts on X were ignored.')
  X = real(X);
end
Xnum = true;
elseif ischar(X)
% continue
elseif iscellstr(X)
Xcell = true;
if Ncol>1
  if Nrow~=1
   error('CVARGAS:saveascii:incorrectXCellSize',...
    'X must be a vector of cell of strings, not a matrix.')
  end
  Nrow = Ncol;
  Ncol = 1;
end
X = X(;
Ncolcell = cellfun(@length,X);
if Nrow==1
  % Cell of length 1?
  X     = X{1};
  Xcell = false;
end
elseif ~Xemp
error('CVARGAS:saveascii:incorrectXType',...
  'X must be numerical, logical, string or cell of strings type.')
end

% CHECKS VARARGIN =========================================================
% Checks number of optional inputs by type.
% Fixed bug with empty inputs. Oct 2009
Nopt   = length(varargin);
inum   = false(1,Nopt);
ichar  = inum;
icell  = inum;
iempty = inum;
for k = 1:Nopt
if     isempty(varargin{k})
  iempty(k) = true;
elseif ischar(varargin{k})
  ichar(k)  = true;
elseif iscellstr(varargin{k})
  icell(k)  = true; % Fixed bug, Oct 2009
elseif isnumeric(varargin{k})
  inum(k)   = true;  % Fixed bug, Oct 2009
else
  error('CVARGAS:saveascii:incorrectTypeInput',...
  'Optional inputs must be numerical, char or cell of strings type.')
end
end

% Checks numeric inputs.
[newFILE,PRE] = get_num(PRE,Ncol,varargin(inum),find(inum),find(iempty));
clear inum iempty

% Gets format.
newFMT = [];
if Xnum
% Checks PRE.
% Avoids a subfunction to optimize memory usage.
if ~isempty(PRE)

  % Rounds down to positive PRE and up to negative PRE.
  ind = (PRE<0);
  if any(ind)
   % Negative PRE.
   if length(PRE)==1
    temp = 10^PRE;
    X    = round(X*temp)/temp;
   else
    temp     = repmat(10.^PRE(ind),Nrow,1);
    X(:,ind) = round(X(:,ind).*temp)./temp;
   end
   clear temp
   PRE(ind) = 0;
  end
  if any(~ind) % (Fixed BUG, Jun 19 2009)
   % Positive PRE.
   if length(PRE)==1
    temp = 10^PRE;
    X    = round(X*temp)/temp;
   else
    temp      = repmat(10.^PRE(~ind),Nrow,1);
    X(:,~ind) = round(X(:,~ind).*temp)./temp;
   end
   clear temp
  end
  X(X==0) = 0; % Forces positive zeros.

  % Generate format from precision.
  % First, creates a short matrix x3 to get the width and helps to save
  % memory, with only 3 rows:
  % 1. Maximum of X columns (ignoring Inf's)
  % 2. Flags if columns of X has: NaN->1; Inf->1; -Inf->-1; otherwise->0
  % 3. Minimum of X columns (ignoring -Inf's)
  iinf  = ~isfinite(X);          %  1's if NaN, Inf or -Inf, 0 otherwise.
  iinfn = find(iinf);            %  To get the -Inf indexes:
  iinfn(isnan(X(iinfn)) ) = [];  % ... deletes the NaN's. Bug fixed mar08
  iinfn(      X(iinfn)>0) = [];  % ... deletes the Inf's
  iinf = double(iinf);           % Turns them to double values
  iinf(iinfn) = -1;              % Put -Inf flags as -1.
  x3 = [maxinf(X,[],1); any(iinf,1)-2*any(iinf<0,1); mininf(X,[],1)];
  clear iinf iinfn
  % Creates the format string from precision options.
  newFMT = pre2fmt(PRE,WID,SPC,Ncol,x3);
  clear x3
end
else
if ~isempty(PRE)
  error('CVARGAS:saveascii:incorrectFmtNumericalInput',...
   'FMT cannot be numerical because X is not numeric.')
end
end

% Checks cell inputs:
[newDLM,newFMT,EOEL,full1] = ...
                         get_cell([],newFMT,EOEL,Ncol,varargin(icell));
clear icell

% Checks string inputs.
% Fixed bug to work with char DELIMITERS besides of cells. Sep 2009.
[newFILE,PER,TOB,WAR,newDLM,newFMT,EOEL,full2] = get_char(newFILE,PER,...
              TOB,WAR,newDLM,newFMT,EOEL,Ncol,varargin(ichar),find(ichar));
clear ichar varargin

% CHECKS FORMAT ===========================================================
% Given FMT?:
if ~isempty(newFMT)
if ~Xnum
  warning('CVARGAS:saveascii:incorrectFmtCharInput',...
   'Ignored specific format because X is char.')
else
  FMT = newFMT;
end
end

% Given DLM:
if ~isempty(newDLM)
if full1 || full2
  warning('CVARGAS:saveascii:ignoredDlmInput',...
   'DLM ignored because FMT is a full format.')
  DLM = {''};
else
  DLM = newDLM;
end
end

% Generates full format:
if ~Xemp
if ~Xcell
  FULLFMT = [BOEL get_strform(DLM,FMT,Ncol) EOEL];
else
  FULLFMT = cell(Nrow,1);
  eoel = EOEL;
  if ~isempty(EOEL)
   for k = 1:2
    if     strcmp(eoel(end-1:end),'\n')
     eoel(end-1:end) = [];
    elseif strcmp(eoel(end-1:end),'\r')
     eoel(end-1:end) = [];
    end
    if isempty(eoel), break, end
   end
  elseif length(FMT)>1
   for k = 1:2
    if isempty(FMT), break, end
    if     strcmp(FMT(end-1:end),'\n')
     EOEL = FMT(end-1:end);
     FMT(end-1:end) = [];
    elseif strcmp(FMT(end-1:end),'\r')
     EOEL = FMT(end-1:end);
     FMT(end-1:end) = [];
    end
   end
  end
  for k = 1:Nrow
   FULLFMT{k}    = [BOEL get_strform(DLM,FMT,Ncolcell(k))    eoel];
  end
end
else
% Empty array.
X       = '';   % Fixed BUG (May 07, 2009)
FULLFMT = '';
end
clear BOEL WID FMT DLM SPC Ncol

% CHECKS FILE =============================================================
% Given FILE?:
if ~isempty(newFILE)
FILE = newFILE;
% Warning for the file id used. To check that FILE is a fid and not a
% precision.
if isempty(PRE) && isempty(newFMT) && isnumeric(FILE)
  if ~isempty(fopen(FILE))
   warning('CVARGAS:saveascii:usedFileNumericalInput',...
    'Filename used was ''%s'' with file identifier %.0f.',fopen(FILE),FILE)
   % To ignore this warning use
   % >> warning('off','CVARGAS:saveascii:usedFileNumericalInput')
   % before calling this program.
  else
   error('CVARGAS:saveascii:invalidNumericalSecondInput',...
    ['Numerical second input must be a valid File Identifier. If it is '...
     'PRECISION, give an empty, [], as second input.'])
  end
end
end
if ~isempty(FILE) && isnumeric(FILE)
% File id:
fid  = FILE;
[FILE,per] = fopen(fid);
if ~ismember(per(1),'aAwW')
  error('CVARGAS:saveascii:noWrittingPermission',...
    ['Filename ''%s'' with file identifier %.0f does not have writting ' ...
     'permision. See FOPEN for details.'],fopen(FILE),FILE)
end
if Xcell && ~ismember(per(1),'aA')
  error('CVARGAS:saveascii:noAppendPermission',...
    ['Filename ''%s'' with file identifier %.0f does not have append ' ...
     'permision. Elements of cell X will overwrite the file each time.']...
     ,fopen(FILE),FILE)
end
else
fid = [];
end
Femp = isempty(FILE);
if (~Femp && WAR) && ((isempty(fileparts(FILE)) && ...
  (exist(fullfile(pwd,FILE),'file')==2)) || (exist(FILE,'file')==2))
% Overwrite warning.
h = questdlg({'Is it OK to overwrite the file:'; [FILE '?']},...
               'saveascii.m','Yes','Cancel','Cancel');
if isempty(h) || ~strcmp(h,'Yes')
  if nargout==0
   clear X
   return
  end
  Femp = true;
end
end
clear newFILE
clear newFMT


% -------------------------------------------------------------------------
% MAIN
% -------------------------------------------------------------------------

% SAVES IN FILE ===========================================================
if ~Femp
% Saves the matrix to the ascii file using FPRINTF.
if ~isempty(fid)
  if ~Xcell
   fprintf(fid,FULLFMT,X.');
  else
   for k = 1:Nrow
    fprintf(fid,FULLFMT{k},X{k}.');
   end
  end
else
  % Fixed bug. Oct 2009
  [DIR FILE EXT] = fileparts(FILE);
  if ~isempty(DIR)
   if ~(exist(DIR,'dir')==7)
    [flag,temp] = mkdir(DIR);
    if ~flag
     error('CVARGAS:saveascii:invalidDirectoryName',...
      'Unable to create the output directory ''%s''.',DIR)
    end
   end
  end
  FILE = fullfile(DIR,[FILE EXT]);
  fid  = fopen(FILE,[PER TOB]);      % 1.
  if fid<0
   error('CVARGAS:incorrectFileStringInput',...
    ['FILE was not a valid file name. If it is a DELIMITER put it ' ...
    'between brackets, {}, or put an empty, [], in the second input.'])
  end
  if ~Xcell
   fprintf(fid,FULLFMT,X.');         % 2.
   fclose(fid);                      % 3. lines of the SAVEASCII v1.0
  else
   % Writes first element and then appends the others.
   fprintf(fid,[FULLFMT{1} EOEL],X{1}.');
   fclose(fid);
   fid = fopen(FILE,['a' TOB]);
   for k = 2:Nrow
    fprintf(fid,[FULLFMT{k} EOEL],X{k}.');
   end
   fclose(fid);
  end
end
if (nargout==0)
  clear X
  return
end
end

% DISPLAYS IN COMMAND WINDOW ==============================================
if nargout==0
if ~Xcell
  % Display string matrix.
  if ~Xnum && (Xemp || isempty(newDLM))         % Fixed BUG (May 07, 2009)
   disp(X)
   clear X
   return
  end
  X = sprintf(FULLFMT,X.');
  if isempty(X)
   % Incorrect FULLFMT.
   error('CVARGAS:saveascii:incorrectFormat',...
    'Incorrect format.')
  end
  Ncol2 = numel(X)/Nrow;
  if isnatural(Ncol2) % Reshapes it into a string matrix.
   Y  = reshape(X,Ncol2,Nrow);
   Yn = double(Y(end,1));
   if all(Yn==double(sprintf(FULLFMT(end-1:end))))
    Y = Y(1:end-1,';
    X = Y;
   else
    warning('CVARGAS:saveascii:matrixNotSquare',...
    ['The displayed string matrix is a vector because the array ' ...
     'cannot be squared with this format.'])
   % NOTE: SAVEASCII tries to convert the output from SPRINTF, which is a
   %       vector string, to a matrix string but fails, probably due to an
   %       incorrect format row.
   end
  elseif ~isempty(X)
   warning('CVARGAS:saveascii:matrixNotSquare',...
    ['The displayed string matrix is a vector because the array ' ...
     'cannot be squared with this format.'])
   % NOTE: SAVEASCII tries to convert the output from SPRINTF, which is a
   %       vector string, to a matrix string but fails, probably due to an
   %       incorrect format row.
  end
  disp(X)
else
  for k = 1:Nrow
   fprintf(1,[FULLFMT{k} EOEL],X{k}.')
  end
end
clear X
return
end

% OUTPUTS VARIABLE ========================================================
% Output or displays the result.
% Displays the result matrix string on the Command Window or as an output
% argument using SPRINTF and DISP.

% Fixed BUG (May 07, 2009).
if ~Xnum && (Xemp || (isempty(newDLM) && ~Xcell))
return
end

% Output string matrix.
if ~Xcell
X     = sprintf(FULLFMT,X.');
Ncol2 = numel(X)/Nrow;
if isnatural(Ncol2) % Reshapes it into a string matrix.
  Y  = reshape(X,Ncol2,Nrow);
  Yn = double(Y(end,1));
  if all(Yn==double(sprintf(FULLFMT(end-1:end))))
   Y = Y(1:end-1,';
   X = Y;
  else
   warning('CVARGAS:saveascii:matrixNotSquare',...
   ['The displayed string matrix is a vector because the array ' ...
    'cannot be squared with this format.'])
  % NOTE: SAVEASCII tries to convert the output from SPRINTF, which is a
  %       vector string, to a matrix string but fails, probably due to an
  %       incorrect format row.
  end
elseif ~isempty(X)
  warning('CVARGAS:saveascii:matrixNotSquare',...
   ['The output string matrix is a vector because the array ' ...
    'cannot be squared with this format.'])
  % NOTE: SAVEASCII tries to convert the output from SPRINTF, which is a
  %       vector string, to a matrix string but fails, probably due to an
  %       incorrect format row.
end
else
Y = cell(Nrow,1);
for k = 1:Nrow
  Y{k} = sprintf(FULLFMT{k},X{1}.');
  X(1) = [];
end
Mcolcell = cellfun(@length,Y);
X = repmat(' ',Nrow,max(Mcolcell));
for k = 1:Nrow
  X(k,1:Mcolcell(k)) = Y{1};
  Y(1) = [];
end
end


% =========================================================================
% SUBFUNCTIONS
% -------------------------------------------------------------------------

function [fid,PRE] = get_num(PRE,Ncol,numopt,inum,iempty)
% Extract precision from options in a vector array.
% New input "iempty". Oct 2009.

% Forces row PRE:
PRE = round(PRE(.');
fid = [];

% Checks no input.
if isempty(numopt)
return
end

% Checks FILE id input.
% Fixed bug to accept 1 and 2 file identifiers. Oct 2009.
if isempty(iempty) && inum(1)==1 && (numel(numopt{1})==1) && ...
  (numopt{1}>0) && isnatural(numopt{1}) && ~isempty(fopen(numopt{1}))
fid       = numopt{1};
numopt(1) = [];
if isempty(numopt)
  return
end
end

% Checks X empty:
if Ncol==0
return
end

% Checks many inputs.
if length(numopt)>1
error('CVARGAS:saveascii:tooManyFmtInput',...
  'More than one FMT precision given.')
end
% Checks values:
if any(~isfinite(numopt{1}))
error('CVARGAS:saveascii:notFiniteFmtInput',...
  'Precision FMT must be all finite.')
end
% Checks size:
nPRE = numel(numopt{1});
if (nPRE~=1) && (nPRE~=Ncol)
error('CVARGAS:saveascii:incorrectFmtLongInput',...
  'Precision FMT vector must have 1 or Ncol integers.')
end
% Checks integer:
if any(~isnatural(numopt{1}))
error('CVARGAS:saveascii:notIntegerFmtInput',...
  'Precision FMT must be integers.')
end
% Forces integers and row vector:
PRE = numopt{1}(.';

function FMT = pre2fmt(PRE,WID,SPC,Ncol,x3)
% Calculates the width for each column and creates the format string for
% each column with that width, precision and delimiter.

% Reduce the size of x3 if a single precision is given.
if length(PRE)==1
x3 = [max(x3(1,); any(x3(2,,2)-2*any(x3(2,<0,2); min(x3(3,)];
end
if isempty(WID)
WID = get_wid(PRE,x3([1 3],);
% Check at least 3 digits when NaN's or INF's:
isbad = logical(x3(2,:));
isbad(isbad) = (WID(isbad)<=3);
WID(isbad) = 3 + any(x3(2,isbad)<0,1);
% Converst from numeric format to format string:
end
FMT = pre2fmtcol(PRE,WID,SPC,Ncol);

function FMT = pre2fmtcol(PRE,WID,SPC,Ncol)
% Creates the format string for each (or every) column from precision,
% width and specifier.

% Added to reduce running time by reducing the usage of INT2STR. Feb 2008
[w,w,iw] = unique(WID);
[p,p,ip] = unique(PRE);
Nw = length(w);
Np = length(p);
Sw = cell(1,Nw);
Sp = cell(1,Np);
for k = 1:Nw
Sw{k} = int2str(WID(w(k)));
end
for k = 1:Np
Sp{k} = int2str(PRE(p(k)));
end
% Checks flag on specifier:
if length(SPC)==2
flag = SPC(1);
SPC(1) = [];
else
flag = '';
end
% Writes the format strings:
FMT = cell(1,1+(Ncol-1)*(Nw*Np~=1));
FMT{1} = ['%' flag Sw{iw(1)} '.' Sp{ip(1)} SPC];
if Nw*Np~=1
for k = 2:Ncol
  FMT{k} = [ '%' flag Sw{iw(k)} '.' Sp{ip(k)} SPC];
end
end

function WID = get_wid(PRE,x)
% Calculates the maximum number of digits for each (or every) column of x.

M      = get_order(x);
M(M<0) = 0;                       % M=0 if 0<x<1
M      = M+1;                     % Adds the first digit.
M      = M+(x<0);                 % Adds the negative character.
% Get the maximum number of characters in each column:
WID = max(M,[],1);              % Max of digits to the right of the dot.
% Adds the precision and the dot characters:
WID = WID + (PRE+1).*(PRE>0);
% If NaN, InF or -Inf sets at least 3, 3 or 4 digits respectively.
isbad        = any(~isfinite(x),1);
isbad(isbad) = (WID(isbad)<=3) | ~isfinite(WID(isbad));
WID(isbad)   = 3 + any(x(:,isbad)<0,1);

function [DLM,FMT,EOEL,full] = get_cell(DLM,FMT,EOEL,Ncol,cellopt)
% Reads cell optional inputs.

% Initializes.
nDLM = 0;
nFMT = double(~isempty(FMT));
full = false;

while ~isempty(cellopt)
n   = length(cellopt{1});
ind = regexp([' ' cellopt{1}{1} ' '],'[^%]%[^%]');
m   = length(ind);
if     (n==1   ) && ((m~=0) && (((m==1) || (m==Ncol)) || (Ncol==0)))
  % FMT for every column.
  FMT = cellopt{1};  nFMT = nFMT+1;
  full = (m==Ncol);
elseif (m==1) && ((n~=0) && ((n==Ncol) || (Ncol==0)))
  % FMT for each column.
  for k = 2:Ncol
   % Checks if all of them are formats.
   ind = regexp([' ' cellopt{1}{k} ' '],'[^%]%[^%]');
   if length(ind)~=1
    error('CVARGAS:saveascii:incorrectFmtCellInput',...
     'Incorrect FMT cell of strings input.')
   end
  end
  FMT = cellopt{1};  nFMT = nFMT+1;
elseif (n==1) && (m==0)
  % DLM for every column.
  DLM = cellopt{1};  nDLM = nDLM+1;
elseif (m==0) && ((n==(Ncol-1)) || (Ncol==0))
  % DLM for each column.
  DLM = cellopt{1};  nDLM = nDLM+1;
else
  if m==0
   error('CVARGAS:saveascii:incorrectCellLengthInput',...
    'DLM cell of string must be of length 1 or Ncol-1.')
  else
   error('CVARGAS:saveascii:incorrectFmtLengthInput',...
    'FMT cell of string must be of length 1 or Ncol.')
  end
end
cellopt(1) = [];
end

% Checks for errors:
if nDLM>1
error('CVARGAS:saveascii:tooManyDlmInput',...
  'More than one DLM given.')
end
if nFMT>1
error('CVARGAS:saveascii:tooManyFmtInput',...
  'More than one FMT given.')
end

% Checks ending of full format:
if full && (length(FMT{1})>1) && (strcmp(FMT{1}(end-1:end),'\n') || ...
  strcmp(FMT{1}(end-1:end),'\r'))
EOEL = '';
end

function [FILE,PER,TOB,WAR,DLM,FMT,EOEL,full] = ...
                  get_char(FILE,PER,TOB,WAR,DLM,FMT,EOEL,Ncol,stropt,ichar)
% Reads string optional inputs.

% Initializes.
nFILE = double(~isempty(FILE));
nPER  = 0;
nDLM  = ~isempty(DLM);
nFMT  = double(~isempty(FMT));
full  = false;

% Checks strings inputs
while ~isempty(stropt)
% Looks for '%' chars.
ind = regexp([' ' stropt{1} ' '],'[^%]%[^%]');
m   = length(ind);
if m~=0 && (((m==1) || (m==Ncol)) || (Ncol==0))
  % Sets FMT:
  FMT  = stropt(1);  nFMT  = nFMT+1;
  full = (m==Ncol);
else
  % Looks for PER or FILE:
  switch stropt{1}
   case {'w','a'}
    PER  = stropt{1};     nPER  = nPER+1;
   case {'wt','at','wb','ab'}
    PER  = stropt{1}(1);  nPER  = nPER+1;
    TOB  = stropt{1}(2);
   case {'w -i'}
    PER  = stropt{1}(1);  nPER  = nPER+1;
    WAR  = true;
   case {'wt -i','wb -i'}
    PER  = stropt{1}(1);  nPER  = nPER+1;
    TOB  = stropt{1}(2);
    WAR  = true;
   otherwise
    if ichar(1)==1
     FILE = stropt{1};     nFILE = nFILE+1;
    else
     if nDLM
      error('CVARGAS:saveascii:incorrectCharInput', ...
       ['Incorrect char input. \n\n' ...
        'Must be a valid OPEN MODE (''a'',''w'') or a valid FILE NAME ' ...
        '(as second input). '])
     end
     DLM = {stropt{1}};
    end
  end
end
stropt(1) = [];
ichar(1)  = [];
end

% Checks for errors:
if nFILE>1
error('CVARGAS:saveascii:tooManyFileInput',...
  'More than one FILE given.')
end
if nPER>1
error('CVARGAS:saveascii:tooManyPermissionsInput',...
  'More than one open file permission given.')
end
if nFMT>1
error('CVARGAS:saveascii:tooManyFmtInput',...
  'More than one FMT given.')
end
if (nPER==1) && (nFILE==0)
warning('CVARGAS:saveascii:ignoredPermissionInput',...
  'Ignored Permission input because no FILE given.')
end

% Checks ending of full format:
if full && (length(FMT{1})>1) && (strcmp(FMT{1}(end-1:end),'\n') || ...
  strcmp(FMT{1}(end-1:end),'\r'))
EOEL = '';
end

function FULLFMT = get_strform(DLM,FMT,Ncol)
% Generates the whole format string from the options or defaults.

FULLFMT = '';
Nf = length(FMT);
% a) Super format:
if Nf==1
Nf = numel(strfind(FMT{1},'%'));
if Nf==Ncol
  FULLFMT = FMT{1};
elseif Nf~=1       % Error in the full format string option.
  error('CVARGAS:saveascii:invalidStrOptionsSize',...
   'Number of format strings must be 0, 1 or Ncol.')
end
end
% b) Piecewise format:
if isempty(FULLFMT)
FULLFMT = FMT{1};
Nd = length(DLM);
if Nd==1           % Single delimiter?
  if Nf==1          %  + single format?
   FULLFMT = [FULLFMT repmat([DLM{1} FMT{1}],1,Ncol-1)];
  else              %  + Ncol formats?
   for k = 2:Ncol
    FULLFMT = [FULLFMT DLM{1} FMT{k}];
   end
  end
elseif Nd==(Ncol-1)  % Ncol-1 delimiters?
  if Nf==1            %   + single format?
   for k = 2:Ncol
    FULLFMT = [FULLFMT DLM{k-1} FMT{1}];
   end
  else              %   + Ncol formats?
   for k = 2:Ncol
    FULLFMT = [FULLFMT DLM{k-1} FMT{k}];
   end
  end
else               %   No delimiters (all failed)
  if Nf==1          %   + single format?
   FULLFMT = repmat(FULLFMT,1,Ncol);
  else              %   + Ncol formats?
   for k = 2:Ncol
    FULLFMT = [FULLFMT FMT{k}];
   end
  end
end
end

function M = get_order(x)
% Gets the order of magnitud in 10 base, i.e., in scientific notation:
%   M = get_order(y)   =>   y = X.XXXXXX x 10^M

if isinteger(x) % Allows integer input: uint8, etc.
x = double(x); % bug fixed Mar 08
end
temp = warning('off','MATLAB:log:logOfZero');
M = floor(log10(abs(x)));       % In cientific notation x = XXX x 10^M.
M(x==0) = 0; % M=0 if x=0. (Bug fixed 10/jan/2008) (bug fixed 05/may/2008)
warning(temp.state,'MATLAB:log:logOfZero')

function y = maxinf(x,varargin)
%MAXINF   Largest component ignoring INF's as posible.
%
%    Y = MAXINF(X) is equivalent to MAX but ignoring INF's. If there is no
%    finite elements, then the INF or -INF value is returned; NaN's are
%    return if all the elements are NaN's.

y = max(x,varargin{:});
iinf = isinf(y);
if any(iinf(:))
xinf = y(iinf);
x(~isfinite(x)) = NaN;
y = max(x,varargin{:});
inan = isnan(y(iinf));
if any(inan(:))
  y(iinf(inan)) = xinf(inan);
end
end

function y = mininf(x,varargin)
%MININF   Smallest component ignoring -INF's as posible.
%
%    Y = MININF(X) is equivalent to MIN but ignoring -INF's. If there is no
%    finite elements, then the INF or -INF value is returned; NaN's are
%    return if all the elements are NaN's.

y = min(x,varargin{:});
iinf = isinf(y);
if any(iinf(:))
xinf = y(iinf);
x(~isfinite(x)) = NaN;
y = min(x,varargin{:});
inan = isnan(y(iinf));
if any(inan(:))
  y(iinf(inan)) = xinf(inan);
end
end

function n = isnatural(n)
%ISNATURAL   Checks if an array has natural numbers.
%   Y = ISNATURAL(X) returns a logical array of the same size as X with
%   ones in the elements of X that are natural numbers
%   (...-2,-1,0,1,2,...), and zeros where not.

%   Written by
%   M.S. Carlos Adrin Vargas Aguilera
%   Physical Oceanography PhD candidate
%   CICESE
%   Mexico, November 2006
%
%   nubeobscura@hotmail.com

n = (n==floor(n)) & isreal(n)  & isnumeric(n) & isfinite(n);


% [EOF]   saveascii.m

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|物探论坛 ( 鄂ICP备12002012号 微信号:iwutan )

GMT+8, 2024-4-30 07:52 , Processed in 0.089370 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表