% export2latex(EPLdata, filename, options) % % This function may be used to export numeric data in a latex file for later % use with, e.g., NumericPlots.sty. % If the data is provided as an 1xK array, each entry of the array will be exported % to the file . Each entry of the array must be a structure which contains % x, y and ident. x and y must be arrays of the same size MxN. If M>1, each column % of the array is exported to the file and may later be used by \Data, where % is the roman representation of the column number. If M=1, the data may later % be used with the latex command \Data % % EPLdata(1, i).x = x-matrix % EPLdata(1, i).y = y-matrix % EPLdata(1, i).ident = identifier (has to be a string without numbers -> % latex command name) % EPLdata(1, i).descr = description (optional) % EPLdata(1, i).group = GroupNr (optional) use numbers from 1 to n to define groups. For % each group, the maximum and minimum values will be written to the output file and may be % accessed with identifier Group where RomanNumber is the roman represenation % of the group number. All data without group or with group number 0 is put into the group % Dummy % EPLdata(1, i).precision (optional) = number of decimal places to be written % filename = filename (with path, without extension) % options (optional) define which output is required % - options.DataBoundaries [true]: if true, the min/max values of the data % will be written to the output file. % - options.AxisBoundaries [false]: if true, values which may be set as % min/max values for the axis are written to the output file. These are % the min/max values -/+ a gap. % - options.AxisBoundariesGap [10]: defines the gap used for the axis % min/max values in percent of the total range of the data. % - options.SuppressWarning [false]: suppresses the warning about max/min values being to % close together % - options.precision [empty]: how many decimal places should be printed for x and y % values. Will be calculated automatically if left empty. % - options.NaNsplit [false]: if true, the data will be split at NaN % values. See \multilistplot for how to plot them. % % function roman.m required to convert a number to its roman representation. % % author: Thomas König % date: 2010/04/01 % ed. by Pfeffer Andreas July 2010 ->Axis nearly tight -> xMaxAxis,xMinAxis,... added % 2010/08/03 Thomas König: Options added % % Copyright 2010 Thomas König, Alexander Michel % % This file is part of NumericPlots. % % NumericPlots is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % any later version. % % NumericPlots is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with NumericPlots. If not, see . function ret = export2latex(EPLdata, filename, options) if size(EPLdata, 1)>1 error('EPLdata must be of size [1, n]'); end % define standard options if ((nargin<3) || ~isfield(options, 'DataBoundaries')) % DataBoundaries should be in the output file (xMin, xMax, yMin, % yMax) options.DataBoundaries = true; end if ~isfield(options, 'AxisBoundaries') % axis boundaries (xMinAxis, xMaxAxis, yMinAxis, yMaxAxis) options.AxisBoundaries = false; end if ~isfield(options, 'AxisBoundariesGap') % gap for the axis boundaries in percent of full scale options.AxisBoundariesGap = 10; end if ~isfield(options, 'SuppressWarning') options.SuppressWarning = false; end if ~isfield(options, 'NaNsplit') options.NaNsplit = false; end % open file if possible [pathstr, ~, ext] = fileparts(filename); if ~isempty(pathstr) && ~exist(pathstr, 'dir') mkdir(pathstr); end if strcmp(ext, '.tex') fname = fullfile(filename); else fname = fullfile([filename, '.tex']); end [fid, msg] = fopen(fname, 'wt'); if fid<0 display(msg); error('Matlab:FileError', 'Could not open the file %s.', fname); end % write file header fprintf(fid, '%% EPLdata written by export2latex\n'); fprintf(fid, '%% date: %s\n\n', date); fprintf(fid, '\\def\\ExpDate{%s}\n', date); fclose(fid); % process data for i=1:size(EPLdata,2) % Ident=''; My = size(EPLdata(i).y, 1); Mx = size(EPLdata(i).x, 1); if ( Mx>1 && Mx~=My ) error('Matlab:export2latex', 'EPLdata.x and EPLdata.y must have the same size or EPLdata.x must have one column only'); end if (any(any(isnan(EPLdata(i).x))) || any(any(isnan(EPLdata(i).y)))) && ~options.NaNsplit error('Matlab:export2latex', 'EPLdata.x or EPLdata.y contain NaN which Latex cannot process. Consider setting options.NaNsplit = true.'); end if ( Mx==1 ) idx_x = ones(1, My); else idx_x = 1:Mx; end % data header if(isfield(EPLdata(1,i), 'descr')) fid = fopen(fname, 'at'); fprintf(fid, '\\expandafter\\def\\csname Descr%s\\endcsname{%s}\n', EPLdata(1,i).ident, EPLdata(1,i).descr); fclose(fid); end if ~isfield(EPLdata(1,i), 'group') EPLdata(1,i).group = 0; end if isempty(EPLdata(1,i).group) EPLdata(1,i).group = 0; end % xMax, xMin, Dx fid = fopen(fname, 'at'); xMax = max(max(EPLdata(1,i).x)); xMin = min(min(EPLdata(1,i).x)); % axis boundaries xMinAxis = xMin-(xMax-xMin)*options.AxisBoundariesGap/100; % -10% axis nearly tight xMaxAxis = xMax+(xMax-xMin)*options.AxisBoundariesGap/100; % +10% axis nearly tight if (abs(xMax-xMin)<1e-16) xMax = 1.0; xMin = -1.0; if ~options.SuppressWarning fprintf('export2latex - Warning: |xMax-xMin|<1e-16\n'); end end DxV = (xMax-xMin)/5; NrUnsigX = 0; while (fix(DxV*10^(NrUnsigX)) == 0) NrUnsigX = NrUnsigX+1; end % yMin, yMax, Dy yMax = max(max(EPLdata(1,i).y)); yMin = min(min(EPLdata(1,i).y)); % axis boundaries yMinAxis = yMin-(yMax-yMin)*options.AxisBoundariesGap/100; % -10% axis nearly tight yMaxAxis = yMax+(yMax-yMin)*options.AxisBoundariesGap/100; % +10% axis nearly tight % save min/max values for groupes group(i) = EPLdata(1,i).group+1; groupXmax(i) = xMax; groupXmin(i) = xMin; groupYmax(i) = yMax; groupYmin(i) = yMin; if (abs(yMax-yMin)<1e-16) yMax = 1.0; yMin = -1.0; if ~options.SuppressWarning fprintf('export2latex - Warning: |yMax-yMin|<1e-16\n'); end end DyV = (yMax-yMin)/5; DxVAxis = (xMaxAxis-xMinAxis)/5; DyVAxis = (yMaxAxis-yMinAxis)/5; NrUnsigYAxis = 0; while (fix(DyVAxis*10^(NrUnsigYAxis)) == 0) NrUnsigYAxis = NrUnsigYAxis+1; end NrUnsigXAxis = 0; while (fix(DxVAxis*10^(NrUnsigXAxis)) == 0) NrUnsigXAxis = NrUnsigXAxis+1; end % check how many significant numbers DyV has. This number will be used for the precision of all Min/Max values so % latex prints all of them with the same number of decimal places. NrUnsigY = 0; while (fix(DyV*10^(NrUnsigY)) == 0) NrUnsigY = NrUnsigY+1; end if options.DataBoundaries fprintf(fid, ['\\expandafter\\def\\csname Data%sXmin\\endcsname{%1.', num2str(NrUnsigX), 'f}\n'], EPLdata(1,i).ident, floor(xMin*10^NrUnsigX)/(10^NrUnsigX)); fprintf(fid, ['\\expandafter\\def\\csname Data%sXmax\\endcsname{%1.', num2str(NrUnsigX), 'f}\n'], EPLdata(1,i).ident, ceil(xMax*10^NrUnsigX)/(10^NrUnsigX)); fprintf(fid, ['\\expandafter\\def\\csname Data%sYmin\\endcsname{%1.', num2str(NrUnsigY), 'f}\n'], EPLdata(1,i).ident, floor(yMin*10^NrUnsigY)/(10^NrUnsigY)); fprintf(fid, ['\\expandafter\\def\\csname Data%sYmax\\endcsname{%1.', num2str(NrUnsigY), 'f}\n'], EPLdata(1,i).ident, ceil(yMax*10^NrUnsigY)/(10^NrUnsigY)); end fprintf(fid, ['\\expandafter\\def\\csname Data%sDxV\\endcsname{%1.', num2str(NrUnsigX), 'f}\n'], EPLdata(1,i).ident, DxV); fprintf(fid, ['\\expandafter\\def\\csname Data%sDyV\\endcsname{%1.', num2str(NrUnsigY), 'f}\n'], EPLdata(1,i).ident, DyV); if options.AxisBoundaries fprintf(fid, ['\\expandafter\\def\\csname Data%sXminAxis\\endcsname{%1.', num2str(NrUnsigX), 'f}\n'], EPLdata(1,i).ident, floor(xMinAxis*10^NrUnsigX)/(10^NrUnsigX)); fprintf(fid, ['\\expandafter\\def\\csname Data%sXmaxAxis\\endcsname{%1.', num2str(NrUnsigX), 'f}\n'], EPLdata(1,i).ident, ceil(xMaxAxis*10^NrUnsigX)/(10^NrUnsigX)); fprintf(fid, ['\\expandafter\\def\\csname Data%sYminAxis\\endcsname{%1.', num2str(NrUnsigY), 'f}\n'], EPLdata(1,i).ident, floor(yMinAxis*10^NrUnsigY)/(10^NrUnsigY)); fprintf(fid, ['\\expandafter\\def\\csname Data%sYmaxAxis\\endcsname{%1.', num2str(NrUnsigY), 'f}\n'], EPLdata(1,i).ident, ceil(yMaxAxis*10^NrUnsigY)/(10^NrUnsigY)); fprintf(fid, ['\\expandafter\\def\\csname Data%sDxV\\endcsname{%1.', num2str(NrUnsigXAxis), 'f}\n'], EPLdata(1,i).ident, DxVAxis); fprintf(fid, ['\\expandafter\\def\\csname Data%sDyV\\endcsname{%1.', num2str(NrUnsigYAxis), 'f}\n'], EPLdata(1,i).ident, DyVAxis); end fclose(fid); % write actual data for j=1:My % what precision is needed to output the data? yyMax = max(EPLdata(1,i).y(idx_x(j),:)); yyMin = min(EPLdata(1,i).y(idx_x(j),:)); if (abs(yyMax-yyMin)<1e-16) yNrPrecision = 1; else yNrPrecision = ceil(log10(10000/(yyMax-yyMin))); end xxMax = max(EPLdata(1,i).x(idx_x(j),:)); xxMin = min(EPLdata(1,i).x(idx_x(j),:)); if (abs(xxMax-xxMin)<1e-16) xNrPrecision = 1; else xNrPrecision = ceil(log10(10000/(xxMax-xxMin))); end if isfield(EPLdata(1,i), 'precision') NrPrecision = EPLdata(1,i).precision; if isempty(NrPrecision) NrPrecision = max(yNrPrecision, xNrPrecision); end else NrPrecision = max(yNrPrecision, xNrPrecision); end % write the data to the file xData = EPLdata(1,i).x(idx_x(j),:); yData = EPLdata(1,i).y(j,:); if My > 1; Ident = roman(num2str(j)); else Ident=''; end; if options.NaNsplit % look for the ranges where the data exists (~isnan) yData(isnan(xData)) = NaN; KeepLooking = true; nrRanges = 0; Ranges = zeros(0); b = 0; while KeepLooking a = find(~isnan(yData((b+1):end)), 1, 'first') + b; if ~isempty(a) b = find(isnan(yData(a:end)), 1, 'first') + a-1; if isempty(b) b = length(yData); KeepLooking = false; end nrRanges = nrRanges+1; Ranges(nrRanges, :) = [a, b-1]; else KeepLooking = false; end end % data does not contain NaN: if nrRanges<1 nrRanges = 1; Ranges(1, :) = [1, length(yData)]; end fid = fopen(fname, 'at'); fprintf(fid, '\\expandafter\\def\\csname Data%s%sNrRanges\\endcsname{%i}\n', EPLdata(1,i).ident, Ident, nrRanges); fclose(fid); for iRange = 1:nrRanges fid = fopen(fname, 'at'); fprintf(fid, '\\expandafter\\def\\csname Data%s%s%i\\endcsname{\n', EPLdata(1,i).ident, Ident, iRange); fclose(fid); dlmwrite(fname, [xData(Ranges(iRange,1):Ranges(iRange,2)); yData(Ranges(iRange,1):Ranges(iRange,2))]', '-append', 'delimiter', ' ', 'precision', ['%.', num2str(NrPrecision), 'f']); fid = fopen(fname, 'at'); fprintf(fid, '}\n\n'); fclose(fid); end else % options.NaN = false fid = fopen(fname, 'at'); fprintf(fid, '\\expandafter\\def\\csname Data%s%s\\endcsname{\n', EPLdata(1,i).ident, Ident); fclose(fid); dlmwrite(fname, [xData; yData]', '-append', 'delimiter', ' ', 'precision', ['%.', num2str(NrPrecision), 'f']); fid = fopen(fname, 'at'); fprintf(fid, '}\n\n'); fclose(fid); end end end % write group values fid = fopen(fname, 'at'); for i = 1:max(group) xMax = max(groupXmax(group==i)); xMin = min(groupXmin(group==i)); yMax = max(groupYmax(group==i)); yMin = min(groupYmin(group==i)); if (abs(yMax-yMin)<1e-16) yMax = 1.0; yMin = -1.0; end if (abs(xMax-xMin)<1e-16) xMax = 1.0; xMin = -1.0; end % axis boundaries xMinAxis = xMin-(xMax-xMin)*options.AxisBoundariesGap/100; xMaxAxis = xMax+(xMax-xMin)*options.AxisBoundariesGap/100; yMinAxis = yMin-(yMax-yMin)*options.AxisBoundariesGap/100; yMaxAxis = yMax+(yMax-yMin)*options.AxisBoundariesGap/100; DxV = (xMax-xMin)/5; DyV = (yMax-yMin)/5; DxVAxis = (xMaxAxis-xMinAxis)/5; DyVAxis = (yMaxAxis-yMinAxis)/5; % check how many significant numbers DyV has. This number will be used for the precision of all Min/Max values so % latex prints all of them with the same number of decimal places. NrUnsigY = 0; while (fix(DyV*10^(NrUnsigY)) == 0) NrUnsigY = NrUnsigY+1; end NrUnsigX = 0; while (fix(DxV*10^(NrUnsigX)) == 0) NrUnsigX = NrUnsigX+1; end NrUnsigYAxis = 0; while (fix(DyVAxis*10^(NrUnsigYAxis)) == 0) NrUnsigYAxis = NrUnsigYAxis+1; end NrUnsigXAxis = 0; while (fix(DxVAxis*10^(NrUnsigXAxis)) == 0) NrUnsigXAxis = NrUnsigXAxis+1; end if i>1.5 ident = strcat('Group', roman(num2str(i-1))); else ident = 'GroupDummy'; end if options.DataBoundaries fprintf(fid, ['\\expandafter\\def\\csname Data%sXmin\\endcsname{%1.', num2str(NrUnsigX), 'f}\n'], ident, floor(xMin*10^NrUnsigX)/(10^NrUnsigX)); fprintf(fid, ['\\expandafter\\def\\csname Data%sXmax\\endcsname{%1.', num2str(NrUnsigX), 'f}\n'], ident, ceil(xMax*10^NrUnsigX)/(10^NrUnsigX)); fprintf(fid, ['\\expandafter\\def\\csname Data%sYmin\\endcsname{%1.', num2str(NrUnsigY), 'f}\n'], ident, floor(yMin*10^NrUnsigY)/(10^NrUnsigY)); fprintf(fid, ['\\expandafter\\def\\csname Data%sYmax\\endcsname{%1.', num2str(NrUnsigY), 'f}\n'], ident, ceil(yMax*10^NrUnsigY)/(10^NrUnsigY)); end fprintf(fid, ['\\expandafter\\def\\csname Data%sDxV\\endcsname{%1.', num2str(NrUnsigX), 'f}\n'], ident, DxV); fprintf(fid, ['\\expandafter\\def\\csname Data%sDyV\\endcsname{%1.', num2str(NrUnsigY), 'f}\n'], ident, DyV); if options.AxisBoundaries fprintf(fid, ['\\expandafter\\def\\csname Data%sXminAxis\\endcsname{%1.', num2str(NrUnsigXAxis), 'f}\n'], ident, floor(xMinAxis*10^NrUnsigXAxis)/(10^NrUnsigXAxis)); fprintf(fid, ['\\expandafter\\def\\csname Data%sXmaxAxis\\endcsname{%1.', num2str(NrUnsigXAxis), 'f}\n'], ident, ceil(xMaxAxis*10^NrUnsigXAxis)/(10^NrUnsigXAxis)); fprintf(fid, ['\\expandafter\\def\\csname Data%sYminAxis\\endcsname{%1.', num2str(NrUnsigYAxis), 'f}\n'], ident, floor(yMinAxis*10^NrUnsigYAxis)/(10^NrUnsigYAxis)); fprintf(fid, ['\\expandafter\\def\\csname Data%sYmaxAxis\\endcsname{%1.', num2str(NrUnsigYAxis), 'f}\n'], ident, ceil(yMaxAxis*10^NrUnsigYAxis)/(10^NrUnsigYAxis)); fprintf(fid, ['\\expandafter\\def\\csname Data%sDxVAxis\\endcsname{%1.', num2str(NrUnsigXAxis), 'f}\n'], ident, DxVAxis); fprintf(fid, ['\\expandafter\\def\\csname Data%sDyVAxis\\endcsname{%1.', num2str(NrUnsigYAxis), 'f}\n'], ident, DyVAxis); end end fclose(fid); ret = 1; end