Skip to content
Snippets Groups Projects
Select Git revision
  • ff3e14656dcbafc647e73646afda235f613461a8
  • master default protected
  • julia protected
  • 6.x protected
  • python-codegen
  • llvm-15
  • 5.x protected
  • 4.6 protected
  • uop
  • rework_pac
  • aux_vars_fix
  • julia-7.0.0
  • julia-6.4.0
  • julia-6.3.0
  • julia-6.2.0
15 results

DynareMain.cc

Blame
  • savejson.m NaN GiB
    function json=savejson(rootname,obj,varargin)
    %
    % json=savejson(rootname,obj,filename)
    %    or
    % json=savejson(rootname,obj,opt)
    % json=savejson(rootname,obj,'param1',value1,'param2',value2,...)
    %
    % convert a MATLAB object (cell, struct or array) into a JSON (JavaScript
    % Object Notation) string
    %
    % author: Qianqian Fang (fangq<at> nmr.mgh.harvard.edu)
    %            created on 2011/09/09
    %
    % $Id$
    %
    % input:
    %      rootname: name of the root-object, if set to '', will use variable name
    %      obj: a MATLAB object (array, cell, cell array, struct, struct array)
    %      filename: a string for the file name to save the output JSON data
    %      opt: a struct for additional options, use [] if all use default
    %        opt can have the following fields (first in [.|.] is the default)
    %
    %        opt.FileName [''|string]: a file name to save the output JSON data
    %        opt.FloatFormat ['%.10g'|string]: format to show each numeric element
    %                         of a 1D/2D array;
    %        opt.ArrayIndent [1|0]: if 1, output explicit data array with
    %                         precedent indentation; if 0, no indentation
    %        opt.ArrayToStruct[0|1]: when set to 0, savejson outputs 1D/2D
    %                         array in JSON array format; if sets to 1, an
    %                         array will be shown as a struct with fields
    %                         "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for
    %                         sparse arrays, the non-zero elements will be
    %                         saved to _ArrayData_ field in triplet-format i.e.
    %                         (ix,iy,val) and "_ArrayIsSparse_" will be added
    %                         with a value of 1; for a complex array, the 
    %                         _ArrayData_ array will include two columns 
    %                         (4 for sparse) to record the real and imaginary 
    %                         parts, and also "_ArrayIsComplex_":1 is added. 
    %        opt.ParseLogical [0|1]: if this is set to 1, logical array elem
    %                         will use true/false rather than 1/0.
    %        opt.NoRowBracket [1|0]: if this is set to 1, arrays with a single
    %                         numerical element will be shown without a square
    %                         bracket, unless it is the root object; if 0, square
    %                         brackets are forced for any numerical arrays.
    %        opt.ForceRootName [0|1]: when set to 1 and rootname is empty, savejson
    %                         will use the name of the passed obj variable as the 
    %                         root object name; if obj is an expression and 
    %                         does not have a name, 'root' will be used; if this 
    %                         is set to 0 and rootname is empty, the root level 
    %                         will be merged down to the lower level.
    %        opt.Inf ['"$1_Inf_"'|string]: a customized regular expression pattern
    %                         to represent +/-Inf. The matched pattern is '([-+]*)Inf'
    %                         and $1 represents the sign. For those who want to use
    %                         1e999 to represent Inf, they can set opt.Inf to '$11e999'
    %        opt.NaN ['"_NaN_"'|string]: a customized regular expression pattern
    %                         to represent NaN
    %        opt.JSONP [''|string]: to generate a JSONP output (JSON with padding),
    %                         for example, if opt.JSON='foo', the JSON data is
    %                         wrapped inside a function call as 'foo(...);'
    %        opt.UnpackHex [1|0]: conver the 0x[hex code] output by loadjson 
    %                         back to the string form
    %        opt.SaveBinary [0|1]: 1 - save the JSON file in binary mode; 0 - text mode.
    %        opt can be replaced by a list of ('param',value) pairs. The param 
    %        string is equivallent to a field in opt.
    % output:
    %      json: a string in the JSON format (see http://json.org)
    %
    % examples:
    %      a=struct('node',[1  9  10; 2 1 1.2], 'elem',[9 1;1 2;2 3],...
    %           'face',[9 01 2; 1 2 3; NaN,Inf,-Inf], 'author','FangQ');
    %      savejson('mesh',a)
    %      savejson('',a,'ArrayIndent',0,'FloatFormat','\t%.5g')
    %
    % license:
    %     BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details
    %
    % -- this function is part of jsonlab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
    %
    
    if(nargin==1)
       varname=inputname(1);
       obj=rootname;
       if(isempty(varname)) 
          varname='root';
       end
       rootname=varname;
    else
       varname=inputname(2);
    end
    if(length(varargin)==1 && ischar(varargin{1}))
       opt=struct('FileName',varargin{1});
    else
       opt=varargin2struct(varargin{:});
    end
    opt.IsOctave=exist('OCTAVE_VERSION','builtin');
    rootisarray=0;
    rootlevel=1;
    forceroot=jsonopt('ForceRootName',0,opt);
    if((isnumeric(obj) || islogical(obj) || ischar(obj) || isstruct(obj) || iscell(obj)) && isempty(rootname) && forceroot==0)
        rootisarray=1;
        rootlevel=0;
    else
        if(isempty(rootname))
            rootname=varname;
        end
    end
    if((isstruct(obj) || iscell(obj))&& isempty(rootname) && forceroot)
        rootname='root';
    end
    json=obj2json(rootname,obj,rootlevel,opt);
    if(rootisarray)
        json=sprintf('%s\n',json);
    else
        json=sprintf('{\n%s\n}\n',json);
    end
    
    jsonp=jsonopt('JSONP','',opt);
    if(~isempty(jsonp))
        json=sprintf('%s(%s);\n',jsonp,json);
    end
    
    % save to a file if FileName is set, suggested by Patrick Rapin
    if(~isempty(jsonopt('FileName','',opt)))
        if(jsonopt('SaveBinary',0,opt)==1)
    	    fid = fopen(opt.FileName, 'wb');
    	    fwrite(fid,json);
        else
    	    fid = fopen(opt.FileName, 'wt');
    	    fwrite(fid,json,'char');
        end
        fclose(fid);
    end
    
    %%-------------------------------------------------------------------------
    function txt=obj2json(name,item,level,varargin)
    
    if(iscell(item))
        txt=cell2json(name,item,level,varargin{:});
    elseif(isstruct(item))
        txt=struct2json(name,item,level,varargin{:});
    elseif(ischar(item))
        txt=str2json(name,item,level,varargin{:});
    else
        txt=mat2json(name,item,level,varargin{:});
    end
    
    %%-------------------------------------------------------------------------
    function txt=cell2json(name,item,level,varargin)
    txt='';
    if(~iscell(item))
            error('input is not a cell');
    end
    
    dim=size(item);
    if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now
        item=reshape(item,dim(1),numel(item)/dim(1));
        dim=size(item);
    end
    len=numel(item);
    padding0=repmat(sprintf('\t'),1,level);
    padding2=repmat(sprintf('\t'),1,level+1);
    if(len>1)
        if(~isempty(name))
            txt=sprintf('%s"%s": [\n',padding0, checkname(name,varargin{:})); name=''; 
        else
            txt=sprintf('%s[\n',padding0); 
        end
    elseif(len==0)
        if(~isempty(name))
            txt=sprintf('%s"%s": []',padding0, checkname(name,varargin{:})); name=''; 
        else
            txt=sprintf('%s[]',padding0); 
        end
    end
    for j=1:dim(2)
        if(dim(1)>1) txt=sprintf('%s%s[\n',txt,padding2); end
        for i=1:dim(1)
           txt=sprintf('%s%s',txt,obj2json(name,item{i,j},level+(dim(1)>1)+1,varargin{:}));
           if(i<dim(1)) txt=sprintf('%s%s',txt,sprintf(',\n')); end
        end
        if(dim(1)>1) txt=sprintf('%s\n%s]',txt,padding2); end
        if(j<dim(2)) txt=sprintf('%s%s',txt,sprintf(',\n')); end
        %if(j==dim(2)) txt=sprintf('%s%s',txt,sprintf(',\n')); end
    end
    if(len>1) txt=sprintf('%s\n%s]',txt,padding0); end
    
    %%-------------------------------------------------------------------------
    function txt=struct2json(name,item,level,varargin)
    txt='';
    if(~isstruct(item))
    	error('input is not a struct');
    end
    dim=size(item);
    if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now
        item=reshape(item,dim(1),numel(item)/dim(1));
        dim=size(item);
    end
    len=numel(item);
    padding0=repmat(sprintf('\t'),1,level);
    padding2=repmat(sprintf('\t'),1,level+1);
    
    if(~isempty(name)) 
        if(len>1) txt=sprintf('%s"%s": [\n',padding0,checkname(name,varargin{:})); end
    else
        if(len>1) txt=sprintf('%s[\n',padding0); end
    end
    for j=1:dim(2)
      if(dim(1)>1) txt=sprintf('%s%s[\n',txt,padding2); end
      for i=1:dim(1)
        names = fieldnames(item(i,j));
        if(~isempty(name) && len==1)
            txt=sprintf('%s%s"%s": {\n',txt,repmat(sprintf('\t'),1,level+(dim(1)>1)+(len>1)), checkname(name,varargin{:})); 
        else
            txt=sprintf('%s%s{\n',txt,repmat(sprintf('\t'),1,level+(dim(1)>1)+(len>1))); 
        end
        if(~isempty(names))
          for e=1:length(names)
    	    txt=sprintf('%s%s',txt,obj2json(names{e},getfield(item(i,j),...
                 names{e}),level+(dim(1)>1)+1+(len>1),varargin{:}));
            if(e<length(names)) txt=sprintf('%s%s',txt,','); end
            txt=sprintf('%s%s',txt,sprintf('\n'));
          end
        end
        txt=sprintf('%s%s}',txt,repmat(sprintf('\t'),1,level+(dim(1)>1)+(len>1)));
        if(i<dim(1)) txt=sprintf('%s%s',txt,sprintf(',\n')); end
      end
      if(dim(1)>1) txt=sprintf('%s\n%s]',txt,padding2); end
      if(j<dim(2)) txt=sprintf('%s%s',txt,sprintf(',\n')); end
    end
    if(len>1) txt=sprintf('%s\n%s]',txt,padding0); end
    
    %%-------------------------------------------------------------------------
    function txt=str2json(name,item,level,varargin)
    txt='';
    if(~ischar(item))
            error('input is not a string');
    end
    item=reshape(item, max(size(item),[1 0]));
    len=size(item,1);
    sep=sprintf(',\n');
    
    padding1=repmat(sprintf('\t'),1,level);
    padding0=repmat(sprintf('\t'),1,level+1);
    
    if(~isempty(name)) 
        if(len>1) txt=sprintf('%s"%s": [\n',padding1,checkname(name,varargin{:})); end
    else
        if(len>1) txt=sprintf('%s[\n',padding1); end
    end
    isoct=jsonopt('IsOctave',0,varargin{:});
    for e=1:len
        if(isoct)
            val=regexprep(item(e,:),'\\','\\');
            val=regexprep(val,'"','\"');
            val=regexprep(val,'^"','\"');
        else
            val=regexprep(item(e,:),'\\','\\\\');
            val=regexprep(val,'"','\\"');
            val=regexprep(val,'^"','\\"');
        end
        val=escapejsonstring(val);
        if(len==1)
            obj=['"' checkname(name,varargin{:}) '": ' '"',val,'"'];
    	if(isempty(name)) obj=['"',val,'"']; end
            txt=sprintf('%s%s%s%s',txt,repmat(sprintf('\t'),1,level),obj);
        else
            txt=sprintf('%s%s%s%s',txt,repmat(sprintf('\t'),1,level+1),['"',val,'"']);
        end
        if(e==len) sep=''; end
        txt=sprintf('%s%s',txt,sep);
    end
    if(len>1) txt=sprintf('%s\n%s%s',txt,padding1,']'); end
    
    %%-------------------------------------------------------------------------
    function txt=mat2json(name,item,level,varargin)
    if(~isnumeric(item) && ~islogical(item))
            error('input is not an array');
    end
    
    padding1=repmat(sprintf('\t'),1,level);
    padding0=repmat(sprintf('\t'),1,level+1);
    
    if(length(size(item))>2 || issparse(item) || ~isreal(item) || ...
       isempty(item) ||jsonopt('ArrayToStruct',0,varargin{:}))
        if(isempty(name))
        	txt=sprintf('%s{\n%s"_ArrayType_": "%s",\n%s"_ArraySize_": %s,\n',...
                  padding1,padding0,class(item),padding0,regexprep(mat2str(size(item)),'\s+',',') );
        else
        	txt=sprintf('%s"%s": {\n%s"_ArrayType_": "%s",\n%s"_ArraySize_": %s,\n',...
                  padding1,checkname(name,varargin{:}),padding0,class(item),padding0,regexprep(mat2str(size(item)),'\s+',',') );
        end
    else
        if(isempty(name))
        	txt=sprintf('%s%s',padding1,matdata2json(item,level+1,varargin{:}));
        else
            if(numel(item)==1 && jsonopt('NoRowBracket',1,varargin{:})==1)
                numtxt=regexprep(regexprep(matdata2json(item,level+1,varargin{:}),'^\[',''),']','');
               	txt=sprintf('%s"%s": %s',padding1,checkname(name,varargin{:}),numtxt);
            else
        	    txt=sprintf('%s"%s": %s',padding1,checkname(name,varargin{:}),matdata2json(item,level+1,varargin{:}));
            end
        end
        return;
    end
    dataformat='%s%s%s%s%s';
    
    if(issparse(item))
        [ix,iy]=find(item);
        data=full(item(find(item)));
        if(~isreal(item))
           data=[real(data(:)),imag(data(:))];
           if(size(item,1)==1)
               % Kludge to have data's 'transposedness' match item's.
               % (Necessary for complex row vector handling below.)
               data=data';
           end
           txt=sprintf(dataformat,txt,padding0,'"_ArrayIsComplex_": ','1', sprintf(',\n'));
        end
        txt=sprintf(dataformat,txt,padding0,'"_ArrayIsSparse_": ','1', sprintf(',\n'));
        if(size(item,1)==1)
            % Row vector, store only column indices.
            txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
               matdata2json([iy(:),data'],level+2,varargin{:}), sprintf('\n'));
        elseif(size(item,2)==1)
            % Column vector, store only row indices.
            txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
               matdata2json([ix,data],level+2,varargin{:}), sprintf('\n'));
        else
            % General case, store row and column indices.
            txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
               matdata2json([ix,iy,data],level+2,varargin{:}), sprintf('\n'));
        end
    else
        if(isreal(item))
            txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
                matdata2json(item(:)',level+2,varargin{:}), sprintf('\n'));
        else
            txt=sprintf(dataformat,txt,padding0,'"_ArrayIsComplex_": ','1', sprintf(',\n'));
            txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
                matdata2json([real(item(:)) imag(item(:))],level+2,varargin{:}), sprintf('\n'));
        end
    end
    txt=sprintf('%s%s%s',txt,padding1,'}');
    
    %%-------------------------------------------------------------------------
    function txt=matdata2json(mat,level,varargin)
    if(size(mat,1)==1)
        pre='';
        post='';
        level=level-1;
    else
        pre=sprintf('[\n');
        post=sprintf('\n%s]',repmat(sprintf('\t'),1,level-1));
    end
    if(isempty(mat))
        txt='null';
        return;
    end
    floatformat=jsonopt('FloatFormat','%.10g',varargin{:});
    %if(numel(mat)>1)
        formatstr=['[' repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf('],\n')]];
    %else
    %    formatstr=[repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf(',\n')]];
    %end
    
    if(nargin>=2 && size(mat,1)>1 && jsonopt('ArrayIndent',1,varargin{:})==1)
        formatstr=[repmat(sprintf('\t'),1,level) formatstr];
    end
    txt=sprintf(formatstr,mat');
    txt(end-1:end)=[];
    if(islogical(mat) && jsonopt('ParseLogical',0,varargin{:})==1)
       txt=regexprep(txt,'1','true');
       txt=regexprep(txt,'0','false');
    end
    %txt=regexprep(mat2str(mat),'\s+',',');
    %txt=regexprep(txt,';',sprintf('],\n['));
    % if(nargin>=2 && size(mat,1)>1)
    %     txt=regexprep(txt,'\[',[repmat(sprintf('\t'),1,level) '[']);
    % end
    txt=[pre txt post];
    if(any(isinf(mat(:))))
        txt=regexprep(txt,'([-+]*)Inf',jsonopt('Inf','"$1_Inf_"',varargin{:}));
    end
    if(any(isnan(mat(:))))
        txt=regexprep(txt,'NaN',jsonopt('NaN','"_NaN_"',varargin{:}));
    end
    
    %%-------------------------------------------------------------------------
    function newname=checkname(name,varargin)
    isunpack=jsonopt('UnpackHex',1,varargin{:});
    newname=name;
    if(isempty(regexp(name,'0x([0-9a-fA-F]+)_','once')))
        return
    end
    if(isunpack)
        isoct=jsonopt('IsOctave',0,varargin{:});
        if(~isoct)
            newname=regexprep(name,'(^x|_){1}0x([0-9a-fA-F]+)_','${native2unicode(hex2dec($2))}');
        else
            pos=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','start');
            pend=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','end');
            if(isempty(pos)) return; end
            str0=name;
            pos0=[0 pend(:)' length(name)];
            newname='';
            for i=1:length(pos)
                newname=[newname str0(pos0(i)+1:pos(i)-1) char(hex2dec(str0(pos(i)+3:pend(i)-1)))];
            end
            if(pos(end)~=length(name))
                newname=[newname str0(pos0(end-1)+1:pos0(end))];
            end
        end
    end
    
    %%-------------------------------------------------------------------------
    function newstr=escapejsonstring(str)
    newstr=str;
    isoct=exist('OCTAVE_VERSION','builtin');
    if(isoct)
       vv=sscanf(OCTAVE_VERSION,'%f');
       if(vv(1)>=3.8) isoct=0; end
    end
    if(isoct)
      escapechars={'\a','\f','\n','\r','\t','\v'};
      for i=1:length(escapechars);
        newstr=regexprep(newstr,escapechars{i},escapechars{i});
      end
    else
      escapechars={'\a','\b','\f','\n','\r','\t','\v'};
      for i=1:length(escapechars);
        newstr=regexprep(newstr,escapechars{i},regexprep(escapechars{i},'\\','\\\\'));
      end
    end