Mercurial > hg > ltpda
diff m-toolbox/classes/+utils/@helper/obj2tex.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/classes/+utils/@helper/obj2tex.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,472 @@ +% OBJ2TEX converts the input data to TeX code +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% DESCRIPTION: OBJ2TEX converts the input data to TeX code +% +% utils.helper.obj2tex(obj) +% txt = utils.helper.obj2tex(obj) Returns the display text +% +% +% HISTORY: 3-09-2010 A. Grynagier +% Creation +% +% VERSION: $Id: obj2tex.m,v 1.2 2010/09/06 17:07:58 adrien Exp $ +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function varargout = obj2tex(varargin) + if nargin~=1 + error(['utils.helper.obj2tex only takes one input object at a time and nargin is ' num2str(nargin)]) + end + %#ok<*AGROW> + obj = varargin{1}; + % objClasses = {'param' 'tsdata' 'data2D' 'paramValue' 'smodel' 'unit' 'data3D' 'parfrac' 'specwin' ... + % 'filterbank' 'pest' 'xydata' 'fsdata' 'matrix' 'plist' 'ssm' 'xyzdata' 'mfir' ... + % 'ssmblock' 'ao' 'ltpda_data' 'miir' 'pz' 'ssmport' 'cdata' 'ltpda_filter' 'pzmodel' 'time'... + % 'collection' 'msym' 'rational' 'timespan'} + % otherClasses = {'double' 'sym' 'char'} + % if numel(obj)~=1 + % error('only takes a single object') + % txt = cell(size(objs)); + % for ii=1:numel(txt) + % txt{ii} = utils.helper.obj2tex(obj(ii)); + % end + % varargout = txt; + % if nargout == 0 + % display(txt) + % end + % return + % elseif numel(obj)==0 + %% special cases for empty objects + if numel(obj)==0 + switch lower(class(obj)) + case {'double' 'logical' 'cell' 'sym'} + otherwise + varargout = {''}; + return + end + end + + %% dealing with objects of size more than one + if numel(obj)>1 + switch lower(class(obj)) + case {'double' 'logical' 'ao' 'ssmblock' 'sym' 'cell' 'char'} + case {'plist' 'units' 'parfrac' 'pest' 'miir' 'rational' 'pzmodel'} + error('multiple objects of this class are not handled yet') + otherwise + varargout = {''}; + return + end + end + + %% dealing with objects + switch lower(class(obj)) + case 'ao' %% ao, does not plot content + txt = ' \begin{tabular}{cll} NAME & DESCRIPTION & DATA \\ \hline \\ '; + for ii=1:numel(obj) + if ii>1 + txt = [txt ' \\ ']; + end + txt = [ txt ' \texttt{' utils.helper.obj2tex(obj(ii).name) '} & ' utils.helper.obj2tex(obj(ii).description) ' & ' utils.helper.obj2tex(obj(ii).data) ]; + end + txt = [txt ' \end{tabular} ']; + + case 'plist' %% plist, does not plot all options so far. A tabular may be better... TBC... + txt = ' \begin{tabular}{cll} KEY & VALUE & DESCRIPTION \\ \hline \\ '; + for ii=1:obj.nparams + if ii>1 + txt = [txt ' \\ ']; + end + txt = [txt ' \texttt{' utils.helper.obj2tex(obj.params(ii).key) '} & $ ' utils.helper.obj2tex( obj.params(ii).getVal ) ' $ ']; + objmin = obj.params(ii).getProperty('min'); + objmax = obj.params(ii).getProperty('max'); + objunits = obj.params(ii).getProperty('units'); + if ~isempty(objmin) && ~isempty(objmax ) + txt = [ txt ' $ \in \left[ ' utils.helper.obj2tex( eval(objmin) ) ';' utils.helper.obj2tex( eval(objmax) ) ' \right] $ ' ]; + end + if ~isempty(objunits) + if ischar( objunits ) + objunits = strrep( objunits , '(' , ''); + objunits = strrep( objunits , ')' , ''); + objunits = strrep( objunits , ' ^' , '^'); + end + txt = [ txt ' $ \, ' utils.helper.obj2tex( unit(objunits) ) ' $ ' ]; + elseif ischar(objunits) + txt = [ txt ' $ \, ' utils.helper.obj2tex( unit ) ' $ ' ]; + end + txt = [txt ' & ' utils.helper.obj2tex( obj.params(ii).desc ) ]; + end + txt = [txt ' \end{tabular} ']; + + case 'param' %% called by the plist function + error('param should always be provided inside a plist object') + + case lower('paramValue') + error('paramValue should always be provided inside a param object') + + case 'smodel' + % { 'expr' 'params' 'values' 'trans' 'xvar' 'xvals' 'xunits' 'yunits' 'name'} + error('smodel is not supported yet') + + case 'unit' + txt = ' \left['; + if numel(obj.strs)==0 + txt = [txt ' - ']; + else + for ii=1:numel(obj.strs) + if ii>1 + txt = [txt ' \,' ]; + end + p = val2prefix(obj.vals(ii)); + if obj.exps(ii) == 0 + elseif obj.exps(ii) == 1 + txt = [txt ' \mathrm{' p ' ' obj.strs{ii} '} ' ]; + else + txt = [txt ' \mathrm{' p ' ' obj.strs{ii} '}^{' num2str(obj.exps(ii)) '}' ]; + end + end + end + txt = [txt ' \right] ']; + + case 'parfrac' + %{ 'res' 'poles' 'pmul' 'dir' 'iunits' 'ounits' 'name' } + display('warning, the parfrac was not tested so far') + txt = [' G_{\texttt{' utils.helper.obj2tex(obj.name) '}} (s) = ']; + for ii=1:numel(obj.res) + if ii>1 + txt = [txt ' + ']; + end + if obj.pmul(ii)>1 + txt = [txt '\frac{ ' utils.helper.obj2tex(obj.res(ii)) ' }{ \left( s-' utils.helper.obj2tex(obj.poles(ii)) ' \right)^{' utils.helper.obj2tex(obj.pmul(ii)) '} }' ]; + elseif obj.pmul(ii)==1 + txt = [txt '\frac{ ' utils.helper.obj2tex(obj.res(ii)) ' }{ s-(' utils.helper.obj2tex(obj.poles(ii)) ') }' ]; + end + end + txt = [txt ' + ' utils.helper.obj2tex(obj.dir) ]; + txt = [txt ' \, ' utils.helper.obj2tex( simplify(obj.ounits/obj.iunits) ) ]; + + case 'filterbank' + %{'filters' 'type' 'name' } + error('filterbank is not supported yet') + + case 'pest' + %{ 'dy' 'y' 'names' 'yunits' 'pdf' 'cov' 'corr' 'chi2' 'dof' 'chain' 'name' } + % plotting names + txt = ' \left[ \begin{array}{c} '; + for ii=1:numel(obj.y) + if ii>1 + txt = [txt ' \\ ' ]; + end + txt = [txt '\mathrm{' utils.helper.obj2tex(obj.names{ii}) '}' ]; + end + txt = [ txt ' \end{array} \right] = ']; + % plotting values + txt = [ txt ' \left[ \begin{array}{rl} ' ]; + for ii=1:numel(obj.y) + if ii>1 + txt = [txt ' \\ ' ]; + end + if ~isempty(obj.dy) + txt = [txt utils.helper.obj2tex(num2str(obj.y(ii))) ' \, \pm \, ' utils.helper.obj2tex(num2str(obj.dy(ii))) ' & ' utils.helper.obj2tex(obj.yunits(ii)) ]; + else + txt = [txt utils.helper.obj2tex(num2str(obj.y(ii))) ' & ' utils.helper.obj2tex(obj.yunits(ii)) ]; + end + end + txt = ' \end{array} \right] '; + if ~isempty(obj.corr) + txt = [txt ' \\ \mathrm{CORR}= \left[ ' utils.helper.obj2tex(obj.corr) ' \right] ']; + end + if ~isempty(obj.cov) + txt = [txt ' \\ \mathrm{COV}= \left[ ' utils.helper.obj2tex(obj.cov) ' \right] ']; + end + if ~isempty(obj.cov) + txt = [txt ' \\ \chi_2 = ' utils.helper.obj2tex(obj.chi2) ]; + end + + case 'matrix' + %{ 'objs' 'name' } + error('matrix is not supported yet') + + case 'ssm' + %{ 'amats' 'bmats' 'cmats' 'dmats' 'timestep' 'inputs' 'states' 'outputs' 'numparams' 'params' ... + % 'Ninputs' 'inputsizes' 'Noutputs' 'outputsizes' 'Nstates' 'statesizes' 'Nnumparams' 'Nparams' 'isnumerical' 'name' } + txt = '\begin{longtable}{|rl|} \hline \textbf{FIELD} & \textbf{PROPERTY} \\ \hline \hline '; + txt = [txt ' \textbf{NAME:} & \texttt{' utils.helper.obj2tex(obj.name) '} ']; + txt = [ txt ' \\ \hline & \\[3pt] \textbf{DESCRIPTION:} & ' utils.helper.obj2tex(obj.description) ' ' ]; + txt = [ txt ' \\ \hline & \\[3pt] \textbf{REALIZATION:} & $ \begin{array}{c|c} A & B \\ \hline C & D \end{array} ' ]; + txt = [ txt ' \sim \begin{array}{c|c} ' utils.helper.obj2tex(obj.amats) ' & ' utils.helper.obj2tex(obj.bmats) ' \\ \hline ' ]; + txt = [ txt utils.helper.obj2tex(obj.cmats) ' & ' utils.helper.obj2tex(obj.dmats) ' \end{array} $']; + txt = [ txt ' \\ \hline \textbf{TIMESTEP:} & ' utils.helper.obj2tex(obj.timestep) ' $' utils.helper.obj2tex( unit('s') ) '$' ]; + txt = [ txt ' \\ \hline & \\[3pt] \textbf{INPUTS:} & ' utils.helper.obj2tex(obj.inputs) ]; + txt = [ txt ' \\ \hline & \\[3pt] \textbf{STATES:} & ' utils.helper.obj2tex(obj.states) ]; + txt = [ txt ' \\ \hline & \\[3pt] \textbf{OUTPUTS:} & ' utils.helper.obj2tex(obj.outputs) ]; + txt = [ txt ' \\ \hline & \\[3pt] \textbf{PARAMS:} & ' utils.helper.obj2tex(obj.params) ]; + txt = [ txt ' \\ \hline & \\[3pt] \textbf{NUMPARAMS:} & ' utils.helper.obj2tex(obj.numparams) ]; + txt = [ txt ' \\ \hline \end{longtable} ' ]; + + case 'mfir' + %{ 'gd' 'ntaps' 'fs' 'a' 'iunits' 'ounits' 'name' } + error('mfir is not supported yet') + + case 'ssmblock' + %{ 'name' 'ports' } + txt = ' \begin{tabular}{r|lcl} BLOCK & PORT & UNITS & DESCRIPTION '; + + for kk = 1:numel(obj) + txt = [txt ' \\ \hline ']; + for ii=1:numel(obj(kk).ports) + [blockName, portName] = ssmblock.splitName(obj(kk).ports(ii).name); + if ~strcmp(blockName, obj(kk).name) + portName = obj(kk).ports(ii).name; + end + if ii>1 + txt = [txt ' \\ ']; + end + if ii==1 + txt = [txt ' \texttt{' utils.helper.obj2tex(obj(kk).name) '} & & & ' utils.helper.obj2tex(obj(kk).description) ' \\ ']; + end + txt = [txt ' & \texttt{' utils.helper.obj2tex(portName) '} & $ ' utils.helper.obj2tex(obj(kk).ports(ii).units) ' $ & ' utils.helper.obj2tex(obj(kk).ports(ii).description) ' ']; + end + end + txt = [ txt ' \end{tabular} ']; + + case 'pz' + %{ 'f' 'q' 'ri'} + if isnan(obj.q) + txt = [' \left( s - 2 \pi \left( ' num2str(obj.f) '\right) \right) ' ]; + else + txt = [' \left( s^2 + 2 \pi \left( \frac{' utils.helper.obj2tex(obj.f) '}{' utils.helper.obj2tex(obj.q) '} \right) s + 4 \pi^2 \left(' utils.helper.obj2tex(abs(obj.f)) '\right)^2 s^2 \right) ' ]; + end + + case 'ssmport' + %{'name' 'units' } + error('ssmports should always be provided inside a ssmblock object') + + case 'pzmodel' + %{ 'poles' 'zeros' 'gain' 'delay' 'iunits' 'ounits' 'name' } + txt = [' G_{\texttt{' utils.helper.obj2tex(obj.name) '}} (s) = ' utils.helper.obj2tex(obj.gain) ' \times \frac{']; + if numel(obj.zeros)>0 + for ii=1:numel(obj.zeros) + txt = [txt utils.helper.obj2tex(obj.zeros(ii)) ]; + end + else + txt = [txt ' 1 ' ]; + end + txt = [ txt ' }{ ']; + if numel(obj.poles)>0 + for ii=1:numel(obj.poles) + txt = [txt utils.helper.obj2tex(obj.poles(ii)) ]; + end + else + txt = [txt ' 1 ' ]; + end + txt = [txt ' } ' utils.helper.obj2tex( simplify(obj.ounits/obj.iunits) ) ]; + + case 'collection' + %{ 'objs' 'name' } + error('collection is not supported yet') + + case 'msym' + %{'use fieldnames'} + txt = obj.s; + txt = strrep(txt, '*', '\times'); + txt = strrep(txt, '(', '{ \left('); + txt = strrep(txt, ')', '\right) }'); + + case 'specwin' + %{ 'type' 'alpha' 'psll' 'rov' 'nenbw' 'w3db' 'flatness' 'ws' 'ws2' 'win'} + error('specwin is not supported yet') + + case 'miir' + %{ 'b' 'ntaps' 'fs' 'a' 'iunits' 'ounits' 'name' } + %{ 'poles' 'zeros' 'gain' 'delay' 'iunits' 'ounits' 'name' } + txt = [' G_{\texttt{' utils.helper.obj2tex(obj.name) '}} (z) = \frac{']; + for ii=1:numel(obj.a) + if ii>1 && obj.a(ii)>=0 + txt = [txt ' + ']; + end + txt = [txt utils.helper.obj2tex(obj.a(ii)) 'z^{-' num2str(ii) '}' ]; + end + txt = [ txt ' }{ ']; + for ii=1:numel(obj.b) + if ii>1 && obj.b(ii)>=0 + txt = [txt ' + ']; + end + txt = [txt utils.helper.obj2tex(obj.b(ii)) 'z^{-' num2str(ii) '}' ]; + end + txt = [txt ' } ' utils.helper.obj2tex( simplify(obj.ounits/obj.iunits) ) ]; + + case 'rational' + %{ 'num' 'den' 'iunits' 'ounits' 'name' } + %{ 'poles' 'zeros' 'gain' 'delay' 'iunits' 'ounits' 'name' } + txt = [' G_{\texttt{' utils.helper.obj2tex(obj.name) '}} (s) = \frac{']; + for ii=1:numel(obj.num) + if ii>1 && obj.num(ii) >=0 + txt = [txt ' + ']; + end + txt = [txt utils.helper.obj2tex(obj.num(ii)) 's^{' num2str(ii) '}' ]; + end + txt = [ txt ' }{ ']; + for ii=1:numel(obj.den) + if ii>1 && obj.den(ii)>=0 + txt = [txt ' + ']; + end + txt = [txt utils.helper.obj2tex(obj.den(ii)) 's^{' num2str(ii) '}' ]; + end + txt = [txt ' } ' utils.helper.obj2tex( simplify(obj.ounits/obj.iunits) ) ]; + + case 'timespan' + %{ 'startT' 'endT' 'interval' 'timeformat' 'timezone' 'name' } + error('timespan is not supported yet') + + case 'tsdata' + %{ 't0' 'fs' 'nsecs' 'xunits' 'yunits' 'x' 'y' 'dx' 'dy'} + txt = [ ' $(1 \times ' utils.helper.obj2tex(numel(obj.y)) ')$ times series, units: $' utils.helper.obj2tex(obj.yunits) '$vs$' utils.helper.obj2tex(obj.xunits) ' $ at $' num2str(obj.fs) '$Hz ']; + + case 'xydata' + txt = [ ' $(1 \times ' utils.helper.obj2tex(numel(obj.y)) ')$ x-y data, units: $' utils.helper.obj2tex(obj.yunits) '$vs$' utils.helper.obj2tex(obj.xunits) '$ ']; + %{ 'xunits' 'yunits' 'x' 'y' 'dx' 'dy'} + + case 'fsdata' + %{ 't0' 'navs' 'fs' 'enbw' 'xunits' 'yunits' 'x' 'y' 'dx' 'dy'} + txt = [ ' $(1 \times ' utils.helper.obj2tex(numel(obj.y)) ')$ frequency series, units: $' utils.helper.obj2tex(obj.yunits) '$vs$' utils.helper.obj2tex(obj.xunits) ' $ up to $' num2str(obj.fs) '$Hz ']; + + case 'xyzdata' + %{ 'zunits' 'z' 'xunits' 'yunits' 'x' 'y' 'dx' 'dy'} + display('warning, xyz data was not tested yet') + txt = [ ' $(' utils.helper.obj2tex(numel(obj.x)) ' \times ' utils.helper.obj2tex(numel(obj.y)) ')$ table, units: $' utils.helper.obj2tex(obj.yunits) '$vs$ \left(' utils.helper.obj2tex(obj.xunits) ' \times ' utils.helper.obj2tex(obj.yunits) '\right)$ ']; + + case 'cdata' + %{ 'yunits' 'y' 'dy'} + error('cdata is not supported yet') + + case 'double' + [n1, n2] = size(obj); + if n1==0 || n2==0 + % array of size 0 + txt = [' 0_{ \left[ ' num2str(n1) ' \times ' num2str(n2) ' \right] } ']; + elseif n1==1 && n2==1 + % array of size 1 + if isnan(obj) + txt = '\mathrm{NaN}'; + elseif isinf(obj) + txt = ' \pm \infty '; + else + if isreal(obj) + txt1 = num2str(obj, '%10.5e'); + [txt2, txt1] = strtok(txt1, 'e'); + expo = eval(txt1(2:end)); + if expo==0 + txt = [ ' ' txt2 ' ' ]; + else + txt = [ ' ' txt2 '.10^{' num2str(expo) '} ' ]; + end + else + if imag(obj)>= 0 + txt = [ ' ' utils.helper.obj2tex( real(obj) ) '+' utils.helper.obj2tex( imag(obj) ) ' i ' ]; + else + txt = [ ' ' utils.helper.obj2tex( real(obj) ) '' utils.helper.obj2tex( imag(obj) ) ' i ' ]; + end + end + end + else + % array of size nxm + txt = ' \left[ \begin{array}{'; + for ii=1:size(obj,2) + txt = [txt 'c' ]; + end + txt = [txt '} ']; + for ii=1:size(obj,1) + for jj=1:size(obj,2) + if jj>1 + txt = [ txt ' & ']; + end + val = obj(ii,jj); + txt = [ txt ' ' utils.helper.obj2tex(val) ]; % reccursive call with a singleton + end + if ii<size(obj,1) + txt = [ txt ' \\ ' ]; + end + end + txt = [ txt ' \end{array} \right] ' ]; + end + + case 'logical' + txt = utils.helper.obj2tex( double(obj) ); + + case 'sym' + error('sym is not supported yet') + + case 'cell' + [n1, n2] = size(obj); + if n1==0 || n2==0 + % array of size 0 + txt = [' \texttt{cell}_{ \left[ ' num2str(n1) ' \times ' num2str(n2) ' \right] } ']; + elseif n1==1 && n2==1 + % array of size 1 + txt = ['{' num2str(size(obj{1},1)) ' \times ' num2str(size(obj{1},2)) ' \texttt{ ' class(obj{1}) '} } ' ]; + else + % array of size mxn + txt = ' \left[ \begin{array}{'; + for ii=1:size(obj,2) + txt = [txt 'c' ]; + end + txt = [txt '} ']; + for ii=1:size(obj,1) + for jj=1:size(obj,2) + if jj>1 + txt = [ txt ' & ']; + end + val = obj{ii,jj}; + txt = [ txt ' {' num2str(size(val,1)) ' \times ' num2str(size(val,2)) ' \texttt{ ' class(val) '} } ' ]; + end + if ii<size(obj,1) + txt = [ txt ' \\ ' ]; + end + end + txt = [ txt ' \end{array} \right] ' ]; + end + + case 'char' + txt = obj; + txt = strrep( txt, '_', '\_'); + txt = strrep( txt, '^', '\^'); + txt = strrep( txt, '->', '$\rightarrow$'); + + otherwise + error(['conversion to TeX is not yet implemented for class ' class(obj) '!']) + end + + if nargout == 0 + display(txt); + elseif nargout == 1 + varargout{1} = txt; + end +end + + + + + + + + + + + + + + + +% private function of unit class + +function p = val2prefix(val) + [pfxs, pfxvals] = unit.supportedPrefixes; + res = val==pfxvals; + if any(res) + p = pfxs{val==pfxvals}; + else + p = ''; + end +end