1 classdef StructDisp < handle
7 [reg,propValCVec]=
self.parseArgList(varargin);
9 {
'isFullCheck';
true;
'islogical(x)&&isscalar(x)'},...
10 [1 1],
'regDefList',{
'isstruct(x)&&isscalar(x)'});
11 [
self.inpPrintValues,
self.structureName,...
12 self.maxArrayLength,
self.depth,
self.numberFormat]=...
14 self.initialize(reg{1});
17 function resStr=char(
self)
20 resStr=[resultString,sprintf('\n')];
25 function [changedRowIndVec,changedColIndVec]=update(self,SStructInp)
27 if ~(isstruct(SStructInp)&&isscalar(SStructInp))
29 'SStructInp must be scalar structure')
32 changedRowIndVec=nan(0,1);
33 changedColIndVec=nan(0,1);
35 [isLocalChanges,changedLeavesPathCVec,changedLeavesValCVec]=...
36 getleaveslist(SStructInp,self.SStruct,self.isFullCheck);
38 if ~isempty(changedLeavesPathCVec)
39 [isLeavesVec,indLeavesVec]=
ismember(changedLeavesPathCVec,...
40 {
self.SLeavesInfoVec.path}.
'); 43 indLeavesVec=indLeavesVec(isLeavesVec); 44 changedLeavesValCVec(~isLeavesVec)=[]; 46 SLeavesInfoVecCur=self.SLeavesInfoVec(indLeavesVec); 47 rowIndCVec={SLeavesInfoVecCur.rowIndVec}.';
48 colIndCVec={SLeavesInfoVecCur.colIndVec}.
'; 49 nLeaves=numel(indLeavesVec); 51 inpCVec=
self.getRecFieldPrintAddArgs();
52 [curDispCVec,outIdVec,curRowIndCVec,curColIndCVec]=...
53 self.recFieldPrint(...
54 {idVec,changedLeavesValCVec},inpCVec{:});
55 if ~isequal(idVec,outIdVec)
56 [~,indLeavesVec]=
ismember(idVec,outIdVec);
57 curRowIndCVec=curRowIndCVec(indLeavesVec);
58 curColIndCVec=curColIndCVec(indLeavesVec);
60 isLocalChanges=isequal(...
61 cellfun(
'length',rowIndCVec),...
62 cellfun(
'length',curRowIndCVec));
65 rowIndVec=rowIndCVec{iLeave};
66 colIndVec=colIndCVec{iLeave};
67 curRowIndVec=curRowIndCVec{iLeave};
68 curColIndVec=curColIndCVec{iLeave};
69 nRows=numel(rowIndVec);
71 self.dispCVec{rowIndVec(iRow)}=...
72 [
self.dispCVec{rowIndVec(iRow)}(...
73 1:(colIndVec(iRow)-1))...
74 curDispCVec{curRowIndVec(iRow)}(...
75 curColIndVec(iRow):end)];
78 self.SStruct=SStructInp;
80 changedRowIndVec=vertcat(rowIndCVec{:});
81 changedColIndVec=vertcat(colIndCVec{:});
88 self.initialize(SStructInp);
90 nRows=numel(
self.dispCVec);
91 changedRowIndVec=(1:nRows).
'; 92 changedColIndVec=ones(nRows,1); 99 function resStr=strucdisp(varargin) 101 import mxberry.core.parseparext; 102 className=mfilename('class'); 103 [reg,propValCVec]=feval([className '.parseArgList
'],... 105 reg=parseparext(reg,{},[1 2],... 106 'regDefList
',{[],''},... 107 'regCheckList
',{'isstruct(x)
','isstring(x)
'}); 110 propValCVec=horzcat(propValCVec,{... 111 eval([className '.DASH_SYMBOL_CODE
']),... 112 eval([className '.FILLER_SYMBOL_CODE
'])}); 114 %%%%% start program %%%%% 115 % start recursive function 116 listStr = mxberry.core.struct.StructDisp.recFieldPrint(SInp, 0,... 119 % 'listStr
' is a cell array containing the output 120 % Now it's time to actually output the data
121 % Default is to output to the command window
122 % However,
if the filename argument is defined, output it into a file
125 % write data to screen
128 resStr=[resultString,sprintf(
'\n')];
130 if ~isempty(fileName)
131 % open file and check
for errors
132 fid = fopen(fileName,
'wt');
134 error(
'Unable to open output file');
137 nListRows=length(listStr);
138 for iListRow = 1 : nListRows
139 fprintf(fid,
'%s\n', listStr{iListRow});
147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
148 %% Private properties and methods
149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151 properties (GetAccess=
private,Constant,Hidden)
152 FILLER_SYMBOL_CODE=32;
154 DEFAULT_MAX_ARRAY_LENGTH=10;
156 DEFAULT_PRINT_VALUES=
true;
157 DEFAULT_NUMBER_FORMAT=
'%g';
158 DEFAULT_NAME =
'Structure';
161 properties (Access=
private,Hidden)
163 dispCVec = cell(0,1);
164 SLeavesInfoVec =
repmat(...
165 struct(
'path',
'',
'rowIndVec',NaN,
'colIndVec',NaN),[0 1]);
174 methods (Access=
private,Hidden)
175 function initialize(
self,SStructInp)
176 self.SStruct=SStructInp;
177 inpCVec=
self.getRecFieldPrintAddArgs();
179 leavesPathCVec,leavesRowIndCVec,leavesColIndCVec]=...
180 self.recFieldPrint(
self.SStruct, inpCVec{:});
181 self.SLeavesInfoVec=
struct(...
182 'path',leavesPathCVec,...
183 'rowIndVec',leavesRowIndCVec,...
184 'colIndVec',leavesColIndCVec);
187 function inpCVec=getRecFieldPrintAddArgs(
self)
188 inpCVec={0,
self.inpPrintValues,
self.structureName,...
189 self.maxArrayLength,
self.depth,
self.numberFormat,...
190 self.DASH_SYMBOL_CODE,
self.FILLER_SYMBOL_CODE};
194 methods (Access=
private,Static,Hidden)
195 function [regCVec,propValCVec]=parseArgList(argCVec)
197 className=mfilename(
'class');
198 [regCVec,~,depthVal,printValuesVal,...
199 maxArrayLengthVal,numberFormatVal,...
201 {
'depth',
'printValues',
'maxArrayLength',...
202 'numberFormat',
'defaultName',;...
203 getConstant(
'DEFAULT_DEPTH'),...
204 getConstant(
'DEFAULT_PRINT_VALUES'),...
205 getConstant(
'DEFAULT_MAX_ARRAY_LENGTH'),...
206 getConstant(
'DEFAULT_NUMBER_FORMAT'),...
207 getConstant(
'DEFAULT_NAME');
208 'isscalar(x)&&isnumeric(x)&&fix(x)==x',...
209 'islogical(x)&&isscalar(x)',...
210 'isscalar(x)&&isnumeric(x)&&fix(x)==x&&x>0',...
213 propValCVec={printValuesVal,structureNameVal,maxArrayLengthVal,...
214 depthVal,numberFormatVal};
216 function res=getConstant(constantName)
217 res=eval([className
'.' constantName]);
221 %% FUNCTION: recFieldPrint
223 function [listStr,leavesPathCVec,leavesRowIndCVec,leavesColIndCVec] = recFieldPrint(Structure, indent, printValues,structureName, maxArrayLength, depth, numberFormat,DASH_SYMBOL_CODE, FILLER_SYMBOL_CODE)
224 className=mfilename(
'class');
225 inpCVec={printValues,...
226 structureName, maxArrayLength, depth, numberFormat,...
227 DASH_SYMBOL_CODE, FILLER_SYMBOL_CODE};
228 isnListStrOnly=nargout>1;
229 % Start to initialiase the cell listStr. This cell is used to store all the
230 % output, as
this is much faster then directly printing it to screen.
233 leavesPathCVec = cell(0,1);
234 leavesRowIndCVec = cell(0,1);
235 leavesColIndCVec = cell(0,1);
238 %
"Structure" can be a scalar or a vector.
239 % In
case of a vector,
this recursive
function is recalled
for each of
240 % the vector elements. But
if the values don
't have to be printed, only 241 % the size of the structure and its fields are printed. 242 if isstruct(Structure) && numel(Structure) > 1 243 if (printValues == 0) 244 varStr = createArraySize(Structure, 'Structure
'); 245 body = feval([className '.recFieldPrint
'],... 246 Structure(1), indent, inpCVec{:}); 247 listStr = [{' '}; {[structureName, varStr]}; body; {' O
'}]; 249 sizeVec = size(Structure); 250 nStruc = min(numel(Structure), maxArrayLength); 251 subIndList=cell(1,length(sizeVec)); 252 for iStruc = 1 : nStruc 253 if (~isscalar(Structure)) 254 [subIndList{:}]=ind2sub(sizeVec,iStruc); 255 indexStr = sprintf('%d,
', [subIndList{:}]); 256 indexStr = horzcat('(
', ... 257 indexStr(1:end-2), ')
'); 259 indexStr = sprintf('(%d)
', iStruc); 262 [body,elemPathCVec,elemRowIndCVec,elemColIndCVec] = ... 263 feval([className '.recFieldPrint
'],... 264 Structure(iStruc), indent, inpCVec{:}); 266 leavesPathCVec=vertcat(leavesPathCVec,... 267 strcat(indexStr,'.
',elemPathCVec)); %#ok<AGROW> 268 leavesRowIndCVec=vertcat(leavesRowIndCVec,... cellfun(@(x)x+nAdd,... 269 elemRowIndCVec,'UniformOutput
',false)); %#ok<AGROW> 270 leavesColIndCVec=vertcat(leavesColIndCVec,... 271 elemColIndCVec); %#ok<AGROW> 273 body = feval([className '.recFieldPrint
'],... 274 Structure(iStruc), indent, inpCVec{:}); 276 listStr = [listStr; {' '}; {[structureName,indexStr]}; body; {' O
'}]; %#ok<AGROW> 278 if (numel(Structure) > maxArrayLength) 279 listStr = [listStr; {' '}; sprintf('<<%d elements more>>
', ... 280 numel(Structure) - maxArrayLength)]; 286 %% Select structure fields 287 % The fields of the structure are distinguished between structure and 288 % non-structure fields. The structure fields are printed first, by 289 % recalling this function recursively. 291 % First, select all fields. 293 if isstruct(Structure) 294 fields = fieldnames(Structure); 298 leavesPathCVec=nan(0,1); 301 % Next, structfun is used to return an boolean array with information of 302 % which fields are of type structure. 306 if isstruct(Structure) 307 valsCVec = struct2cell(Structure); 309 valsCVec=Structure{2}; 311 isStructVec = cellfun('isclass
', valsCVec, 'struct'); 312 % Finally, select all the structure fields 314 strucFields = fields(isStructVec); 315 strucVals = valsCVec(isStructVec); 317 %% Recursively print structure fields 318 % The next step is to select each structure field and handle it 319 % accordingly. Each structure can be empty, a scalar, a vector or a matrix. 320 % Matrices and long vectors are only printed with their fields and not with 321 % their values. Long vectors are defined as vectors with a length larger 322 % then the maxArrayLength value. The fields of an empty structure are not 324 % It is not necessary to look at the length of the vector if the values 325 % don't have to be printed, as the fields of a vector or matrix structure
326 % are the same
for each element.
328 % First, some indentation calculations are required.
330 [strIndent, strIndent2] = getIndentation(indent + 1);
331 listStr = [listStr; {strIndent2}];
333 % Next, select each field seperately and handle it accordingly
335 nFields = length(strucFields);
336 for iField = 1 : nFields
337 fieldName = strucFields{iField};
338 fieldVal = strucVals{iField};
342 isPrintWithSize=isempty(fieldVal);
344 if isscalar(fieldVal)
345 %line = sprintf(
'%s |--- %s', strIndent, fieldName);
346 line = horzcat(strIndent,
' |--- ', fieldName);
347 % Recall
this function if the tree depth is not reached yet
348 if (depth < 0) || (indent + 1 < depth)
350 [lines,curPathCVec,curRowIndCVec,curColIndCVec] = ...
351 feval([className
'.recFieldPrint'],...
352 fieldVal, indent + 1, inpCVec{:});
353 isLeaves = ~isempty(curPathCVec);
354 curRowIndCVec = cellfun(@(x)x+1,...
355 curRowIndCVec,
'UniformOutput',
false);
357 lines = feval([className
'.recFieldPrint'],...
358 fieldVal, indent + 1, inpCVec{:});
360 curListStr = [{line}; lines; ...
361 {[strIndent
' | O']}];
364 line = horzcat(line,
' :',...
365 createArraySize(fieldVal,
'Structure')); %#ok<AGROW>
370 % Short vector structure of which the values should be printed
371 elseif (length(fieldVal) < maxArrayLength) && ...
372 ((depth < 0) || (indent + 1 < depth))
374 subIndList=cell(1,ndims(fieldVal));
375 sizeVec=size(fieldVal);
377 % Use a
for-loop to print all structures in the array
378 nFieldElement = numel(fieldVal);
381 curPathCVec = cell(0,1);
382 curRowIndCVec = cell(0,1);
383 curColIndCVec = cell(0,1);
385 for iFieldElement = 1 : nFieldElement
386 [subIndList{:}]=ind2sub(sizeVec,iFieldElement);
387 indexStr=sprintf(
'%d ',horzcat(subIndList{:}));
388 indexStr=indexStr(1:end-1);
389 elemName=horzcat(
'[',indexStr,
']');
391 %line = sprintf(
'%s |--- %s(%s)', ...
392 % strIndent, fieldName, elemName);
393 line = horzcat(strIndent,
' |--- ',...
394 fieldName,
'(', elemName,
')');
396 [lines,elemPathCVec,...
397 elemRowIndCVec,elemColIndCVec] = ...
398 feval([className
'.recFieldPrint'],...
399 fieldVal(iFieldElement), indent + 1, inpCVec{:});
400 if ~isempty(elemPathCVec)
401 nAdd=numel(curListStr);
402 curPathCVec=vertcat(curPathCVec,...
403 strcat(
'(',strrep(indexStr,
' ',
','),
').',...
404 elemPathCVec)); %#ok<AGROW>
405 curRowIndCVec=vertcat(curRowIndCVec,...
406 cellfun(@(x)x+nAdd+1,elemRowIndCVec,...
407 'UniformOutput',
false)); %#ok<AGROW>
408 curColIndCVec=vertcat(curColIndCVec,...
409 elemColIndCVec); %#ok<AGROW>
412 lines = feval([className
'.recFieldPrint'],...
413 fieldVal(iFieldElement), indent + 1, inpCVec{:});
415 curListStr = [curListStr;{line}; lines; ...
416 {[strIndent
' | O'];[strIndent
' | ']}]; %#ok<AGROW>
420 isLeaves=~isempty(curPathCVec);
423 isPrintWithSize=
true;
426 % Structure printed with size only
429 strSize = createArraySize(fieldVal,
'Structure');
430 %line = sprintf(
'%s |--- %s :%s', ...
431 % strIndent, fieldName, strSize);
432 line = horzcat(strIndent,
' |--- ', fieldName,...
435 line = horzcat(strIndent,
' |--- ', fieldName);
442 if curPathCVec{1}(1)==
'(' 443 leavesPathCVec=vertcat(leavesPathCVec,...
444 strcat(fieldName,curPathCVec)); %#ok<AGROW>
446 leavesPathCVec=vertcat(leavesPathCVec,...
447 strcat(fieldName,
'.',curPathCVec)); %#ok<AGROW>
449 leavesRowIndCVec=vertcat(leavesRowIndCVec,...
450 cellfun(@(x)x+nAdd,curRowIndCVec,...
451 'UniformOutput',
false)); %#ok<AGROW>
452 leavesColIndCVec=vertcat(leavesColIndCVec,...
453 curColIndCVec); %#ok<AGROW>
455 % Some extra blank lines to increase readability
456 listStr = [listStr; curListStr; {[strIndent
' | ']}]; %#ok<AGROW>
457 end % End iField
for-loop
460 % To properly align the field names, a filler is required. To know how
long 461 % the filler must be, the length of the longest fieldname must be found.
462 % Because
'fields' is a cell array, the
function 'cellfun' can be used to
463 % extract the lengths of all fields.
465 maxFieldLength = max(cellfun(
'length', fields));
470 %% Print non-structure fields without values
471 % Print non-structure fields without the values. This can be done very
474 noStrucFields = fields(~isStructVec);
475 nFields = length(noStrucFields);
476 fieldListStr = cell(nFields, 1);
477 for iField = 1 : nFields
478 fieldName = noStrucFields{iField};
479 filler = char(ones(1, ...
480 maxFieldLength - length(fieldName) + 2) * DASH_SYMBOL_CODE);
481 fieldListStr{iField} = [strIndent
' |' filler
' ' fieldName];
483 listStr = vertcat(listStr, fieldListStr);
488 %% Select non-structure fields (to print with values)
489 % Select fields that are not a structure and group them by data type. The
490 % following groups are distinguished:
491 % - characters and strings
500 % Character or string (array of characters)
501 isnProcessedVec=~isStructVec;
502 if any(isnProcessedVec)
503 isCharVec = isnProcessedVec;
504 isCharVec(isnProcessedVec) = ...
505 cellfun(
'isclass', valsCVec(isnProcessedVec),
'char');
506 charFields = fields(isCharVec);
507 charVals = valsCVec(isCharVec);
508 isnProcessedVec(isnProcessedVec)=~isCharVec(isnProcessedVec);
514 if any(isnProcessedVec)
515 isLogicalVec = isnProcessedVec;
516 isLogicalVec(isnProcessedVec) = ...
517 cellfun(
'isclass', valsCVec(isnProcessedVec),
'logical');
518 logicalFields = fields(isLogicalVec);
519 logicalVals = valsCVec(isLogicalVec);
520 isnProcessedVec(isnProcessedVec)=~isLogicalVec(isnProcessedVec);
526 if any(isnProcessedVec)
527 isCellVec = isnProcessedVec;
528 isCellVec(isnProcessedVec) = ...
529 cellfun(
'isclass', valsCVec(isnProcessedVec),
'cell');
530 cellFields = fields(isCellVec);
531 cellVals = valsCVec(isCellVec);
532 isnProcessedVec(isnProcessedVec)=~isCellVec(isnProcessedVec);
538 if any(isnProcessedVec)
539 isEmptyVec = isnProcessedVec;
540 isEmptyVec(isnProcessedVec) = ...
541 cellfun(
'isempty', valsCVec(isnProcessedVec));
542 emptyFields = fields(isEmptyVec);
543 isnProcessedVec(isnProcessedVec)=~isEmptyVec(isnProcessedVec);
549 if any(isnProcessedVec)
550 isNumericVec = isnProcessedVec;
551 isNumericVec(isnProcessedVec) = ...
552 cellfun(@isnumeric, valsCVec(isnProcessedVec));
553 isnProcessedVec(isnProcessedVec)=...
554 ~isNumericVec(isnProcessedVec);
558 isScalarVec = isNumericVec;
559 isScalarVec(isNumericVec) = ...
560 cellfun(
'prodofsize', valsCVec(isNumericVec)) == 1;
561 scalarFields = fields(isScalarVec);
562 scalarVals = valsCVec(isScalarVec);
563 isNumericVec(isScalarVec)=
false;
568 % Numeric vectors (arrays)
570 isVectorVec = isNumericVec;
571 isVectorVec(isNumericVec) = ...
572 cellfun(@isvector, valsCVec(isNumericVec));
573 vectorFields = fields(isVectorVec);
574 vectorVals = valsCVec(isVectorVec);
575 isNumericVec(isVectorVec)=
false;
580 % Numeric matrix with dimension size 2 or higher
582 %isMatrix = structfun(@(x) ndims(x) >= 2, Structure);
583 %isMatrix = isMatrix .* isNumeric .* not(isVector) ...
584 % .* not(isScalar) .* not(isEmpty);
585 matrixFields = fields(isNumericVec);
586 matrixVals = valsCVec(isNumericVec);
596 % Datatypes that are not checked
for 597 if any(isnProcessedVec)
598 otherFields = fields(isnProcessedVec);
599 otherVals = valsCVec(isnProcessedVec);
604 %% Print non-structure fields
605 % Print all the selected non structure fields
606 % - Strings are printed to a certain amount of characters
607 % - Vectors are printed as
long as they are shorter than maxArrayLength
608 % - Matrices are printed
if they have less elements than maxArrayLength
609 % - The values of cells are not printed
612 % Start with printing strings and characters. To avoid the display screen
613 % becoming a mess, the part of the
string that is printed is limited to 31
614 % characters. In the future
this might become an optional parameter in
this 615 %
function, but
for now, it is placed in the code itself.
616 %
if the
string is longer than 31 characters, only the first 31 characters
617 % are printed, plus three dots to denote that the
string is longer than
621 nFields = length(charFields);
622 fieldListStr = cell(nFields, 1);
624 fieldColIndVec = nan(nFields, 1);
626 for iField = 1 : nFields
627 fieldName = getFieldName(charFields,iField);
628 fieldVal = charVals{iField};
629 filler = char(ones(1, maxFieldLength - length(fieldName) + 2)...
631 if (size(fieldVal, 1) > 1) && (size(fieldVal, 2) > 1)
632 varStr = createArraySize(fieldVal,
'char');
633 % elseif length(Field) > maxStrLength
634 % varStr = sprintf(
' ''%s...''', Structure.(Field(1:maxStrLength)));
636 %varStr = sprintf(
' ''%s''', fieldVal);
637 varStr = horzcat(
' ''', reshape(fieldVal,1,[]),
''''); 639 fieldListStr{iField} = [strIndent ' |
' filler ' ' fieldName ' :
' varStr]; 641 fieldColIndVec(iField) = numel(fieldListStr{iField})-numel(varStr)+2; 646 leavesPathCVec = vertcat(leavesPathCVec,charFields); 647 leavesRowIndCVec = vertcat(leavesRowIndCVec,... 648 num2cell(numel(listStr)+(1:nFields).'));
649 leavesColIndCVec = vertcat(leavesColIndCVec,...
652 listStr = vertcat(listStr, fieldListStr);
655 %% Print empty fields
656 nFields = length(emptyFields);
657 fieldListStr = cell(nFields, 1);
659 fieldColIndVec = nan(nFields, 1);
661 for iField = 1 : nFields
662 fieldName = getFieldName(emptyFields,iField);
663 filler = char(ones(1, maxFieldLength - length(fieldName) + 2)...
665 fieldListStr{iField} = [strIndent
' |' filler
' ' fieldName
' : [ ]' ];
667 fieldColIndVec(iField) = numel(fieldListStr{iField})-2;
672 leavesPathCVec = vertcat(leavesPathCVec,emptyFields);
673 leavesRowIndCVec = vertcat(leavesRowIndCVec,...
674 num2cell(numel(listStr)+(1:nFields).
')); 675 leavesColIndCVec = vertcat(leavesColIndCVec,... 676 num2cell(fieldColIndVec)); 678 listStr = vertcat(listStr, fieldListStr); 680 %% Print logicals. If it is a scalar, print true/false, else print vector 682 nFields = length(logicalFields); 683 fieldListStr = cell(nFields, 1); 685 fieldColIndVec = nan(nFields, 1); 687 for iField = 1 : nFields 688 fieldName = getFieldName(logicalFields,iField); 689 fieldVal = logicalVals{iField}; 690 filler = char(ones(1, maxFieldLength - length(fieldName) + 2)... 692 if (isscalar(fieldVal)) 698 elseif (isvector(fieldVal) && ... 699 length(fieldVal) <= maxArrayLength) 700 varStr = repmat({'false '},1,numel(fieldVal)); 702 varStr(fieldVal) = {'true '}; 704 varStr = horzcat(varStr{:}); 705 varStr = [' [
' varStr(1:length(varStr) - 1) ']
']; 707 varStr = createArraySize(fieldVal, 'Logic array
'); 709 fieldListStr{iField} = [strIndent ' |
' filler ' ' fieldName ' :
' varStr]; 711 fieldColIndVec(iField) = numel(fieldListStr{iField})-numel(varStr)+2; 716 leavesPathCVec = vertcat(leavesPathCVec,logicalFields); 717 leavesRowIndCVec = vertcat(leavesRowIndCVec,... 718 num2cell(numel(listStr)+(1:nFields).'));
719 leavesColIndCVec = vertcat(leavesColIndCVec,...
722 listStr = vertcat(listStr, fieldListStr);
725 % Print numeric scalar field. The %g format is used, so that integers
726 % floats and exponential numbers are printed in their own format.
728 nFields = length(scalarFields);
729 fieldListStr = cell(nFields, 1);
731 fieldColIndVec = nan(nFields, 1);
733 for iField = 1 : nFields
734 fieldName = getFieldName(scalarFields,iField);
735 fieldVal = scalarVals{iField};
736 filler = char(ones(1, maxFieldLength - length(fieldName) + 2)...
738 varStr = sprintf([
' ',numberFormat], fieldVal);
739 fieldListStr{iField} = [strIndent
' |' filler
' ' fieldName
' :' varStr];
741 fieldColIndVec(iField) = numel(fieldListStr{iField})-numel(varStr)+2;
746 leavesPathCVec = vertcat(leavesPathCVec,scalarFields);
747 leavesRowIndCVec = vertcat(leavesRowIndCVec,...
748 num2cell(numel(listStr)+(1:nFields).
')); 749 leavesColIndCVec = vertcat(leavesColIndCVec,... 750 num2cell(fieldColIndVec)); 752 listStr = vertcat(listStr, fieldListStr); 755 %% Print numeric array. If the length of the array is smaller then 756 % maxArrayLength, then the values are printed. Else, print the length of 759 nFields = length(vectorFields); 760 fieldListStr = cell(nFields, 1); 762 fieldColIndVec = nan(nFields, 1); 764 for iField = 1 : nFields 765 fieldName = getFieldName(vectorFields,iField); 766 fieldVal = vectorVals{iField}; 767 filler = char(ones(1, maxFieldLength - length(fieldName) + 2)... 769 if length(fieldVal) > maxArrayLength 770 varStr = createArraySize(fieldVal, 'Array
'); 772 varStr = sprintf([numberFormat,' '], fieldVal); 773 varStr = [' [
' varStr(1:length(varStr) - 1) ']
']; 775 fieldListStr{iField} = [strIndent ' |
' filler ' ' fieldName ... 778 fieldColIndVec(iField) = numel(fieldListStr{iField})-numel(varStr)+2; 783 leavesPathCVec = vertcat(leavesPathCVec,vectorFields); 784 leavesRowIndCVec = vertcat(leavesRowIndCVec,... 785 num2cell(numel(listStr)+(1:nFields).'));
786 leavesColIndCVec = vertcat(leavesColIndCVec,...
789 listStr = vertcat(listStr, fieldListStr);
791 %% Print numeric matrices. If the matrix is two-dimensional and has more
792 % than maxArrayLength elements, only its size is printed.
793 % If the matrix is
'small', the elements are printed in a matrix structure.
794 % The top and the bottom of the matrix is indicated by a horizontal line of
795 % dashes. The elements are also lined out by
using a format defined by
796 % numberFormat. Because the name of the matrix is only printed on the first
797 % line, the space is occupied by
this name must be filled up on the other
798 % lines. This is done by defining a
'filler2'.
799 % This method was developed by S. Wegerich.
801 nFields = length(matrixFields);
803 fieldRowIndCVec = cell(nFields, 1);
804 fieldColIndCVec = cell(nFields, 1);
806 for iField = 1 : nFields
807 fieldName = getFieldName(matrixFields,iField);
808 fieldVal = matrixVals{iField};
809 filler = char(ones(1, maxFieldLength - length(fieldName) + 2)...
811 if numel(fieldVal) > maxArrayLength
812 varStr = createArraySize(fieldVal,
'Array');
813 varCell = {[strIndent
' |' filler
' ' fieldName
' :' varStr]};
815 fieldRowIndCVec{iField} = numel(listStr)+1;
816 fieldColIndCVec{iField} = numel(varCell{:})-numel(varStr)+2;
819 % matrixSize = size(Structure.(Field));
820 % filler2 = char(ones(1, maxFieldLength + 6) * FILLER_SYMBOL_CODE);
821 % dashes = char(ones(1, 12 * matrixSize(2) + 1) * DASH_SYMBOL_CODE);
822 printedFieldValue=cellfun(@(x)sprintf(numberFormat,x),...
823 num2cell(fieldVal),
'UniformOutput',
false);
825 [varCell,fieldRowIndCVec{iField},fieldColIndCVec{iField}]=...
826 formCellOfString(strIndent,printedFieldValue,...
827 maxFieldLength,[filler
' ' fieldName],...
828 FILLER_SYMBOL_CODE,DASH_SYMBOL_CODE);
829 fieldRowIndCVec{iField}=fieldRowIndCVec{iField}+numel(listStr);
831 varCell=formCellOfString(strIndent,printedFieldValue,...
832 maxFieldLength,[filler
' ' fieldName],...
833 FILLER_SYMBOL_CODE,DASH_SYMBOL_CODE);
836 listStr = [listStr; varCell]; %#ok<AGROW>
838 if nFields&&isnListStrOnly
839 leavesPathCVec=vertcat(leavesPathCVec,matrixFields);
840 leavesRowIndCVec = vertcat(leavesRowIndCVec,fieldRowIndCVec);
841 leavesColIndCVec = vertcat(leavesColIndCVec,fieldColIndCVec);
843 %% Print cell array information, i.e. the size of the cell array. The
844 % content of the cell array is not printed.
845 nFields = length(cellFields);
847 fieldRowIndCVec = cell(nFields, 1);
848 fieldColIndCVec = cell(nFields, 1);
850 for iField = 1 : nFields
851 fieldName = getFieldName(cellFields,iField);
852 fieldVal = cellVals{iField};
853 filler = char(ones(1, maxFieldLength - length(fieldName) + 2)...
855 isMatOfStrings=ismatrix(fieldVal)&&...
856 iscellstr(fieldVal)&&...
857 all(all((cellfun(
'size',fieldVal,1)==1)&...
858 (cellfun(
'ndims',fieldVal)==2)));
860 varCell = {[strIndent
' |' filler
' ' fieldName
' : {}']};
862 fieldRowIndCVec{iField} = numel(listStr)+1;
863 fieldColIndCVec{iField} = numel(varCell{:})-1;
865 elseif (numel(fieldVal) > maxArrayLength)||~isMatOfStrings
866 varStr = createArraySize(fieldVal,
'Cell');
867 varCell = {[strIndent
' |' filler
' ' fieldName
' :' varStr]};
869 fieldRowIndCVec{iField} = numel(listStr)+1;
870 fieldColIndCVec{iField} = numel(varCell{:})-numel(varStr)+2;
874 [varCell,fieldRowIndCVec{iField},fieldColIndCVec{iField}]=...
875 formCellOfString(strIndent,fieldVal,...
876 maxFieldLength,[filler
' ' fieldName],...
877 FILLER_SYMBOL_CODE,DASH_SYMBOL_CODE);
878 fieldRowIndCVec{iField}=fieldRowIndCVec{iField}+numel(listStr);
881 formCellOfString(strIndent,fieldVal,...
882 maxFieldLength,[filler
' ' fieldName],...
883 FILLER_SYMBOL_CODE,DASH_SYMBOL_CODE);
886 listStr = [listStr; varCell]; %#ok<AGROW>
888 if nFields&&isnListStrOnly
889 leavesPathCVec=vertcat(leavesPathCVec,cellFields);
890 leavesRowIndCVec = vertcat(leavesRowIndCVec,fieldRowIndCVec);
891 leavesColIndCVec = vertcat(leavesColIndCVec,fieldColIndCVec);
893 %% Print unknown datatypes. These include objects and user-defined classes
894 nFields = length(otherFields);
895 fieldListStr = cell(nFields, 1);
897 fieldColIndVec = nan(nFields, 1);
899 for iField = 1 : nFields
900 fieldName = getFieldName(otherFields,iField);
901 fieldVal = otherVals{iField}; %#ok<NASGU>
902 filler = char(ones(1, maxFieldLength - length(fieldName) + 2)...
904 varStr=[
' ',evalc(
'display(fieldVal)')];
905 varStr=varStr(1:end-1);
906 fieldListStr{iField} = [strIndent
' |' filler
' ' fieldName
' :' varStr];
908 fieldColIndVec(iField) = numel(fieldListStr{iField})-numel(varStr)+2;
913 leavesPathCVec = vertcat(leavesPathCVec,otherFields);
914 leavesRowIndCVec = vertcat(leavesRowIndCVec,...
915 num2cell(numel(listStr)+(1:nFields).
')); 916 leavesColIndCVec = vertcat(leavesColIndCVec,... 917 num2cell(fieldColIndVec)); 919 listStr = vertcat(listStr, fieldListStr); 922 function fieldName=getFieldName(fieldNameList,iElem) 923 if iscell(fieldNameList) 924 fieldName=fieldNameList{iElem}; 933 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 937 function [varCell,rowIndVec,colIndVec]=formCellOfString(strIndent,fieldValue,maxFieldLength,filler,FILLER_SYMBOL_CODE,DASH_SYMBOL_CODE) 938 isnVarCellOnly=nargout>1; 939 matrixSize=size(fieldValue); 940 maxStringLength=max(max(cellfun('length
',fieldValue))); 941 nVals = numel(fieldValue); 942 %adjustedFieldValue=cellfun(@(x)[x,... 943 % repmat(' ',1,maxStringLength-length(x)),'|
'],... 944 % fieldValue,'UniformOutput
',false); 945 addLenVec=maxStringLength-cellfun('length
',fieldValue(:)); 947 adjustedFieldValue=cell(matrixSize); 949 adjustedFieldValue{iVal}=horzcat(fieldValue{iVal},... 950 space(ones(1,addLenVec(iVal))),'|
'); 952 nDashes=(maxStringLength+1)* matrixSize(2)+1; 953 filler2 = char(ones(1, maxFieldLength + 6) * ... 955 dashes = char(ones(1, nDashes)* ... 957 nRows = size(adjustedFieldValue,1); 958 varCell = cell(nRows+2,1); 960 rowIndVec=(1:nRows+2).';
961 colIndVec=nan(nRows+2,1);
964 prefixStr=[strIndent
' |' filler2];
966 colIndVec(1)=numel(prefixStr)+1;
968 varCell{1} = [prefixStr dashes];
970 % first line with field name
971 prefixStr=[strIndent
' |' filler
' : |'];
972 varStr=[adjustedFieldValue{1,:}];
974 colIndVec(2)=numel(prefixStr)+1;
976 varCell{2} =[prefixStr varStr];
978 % second and higher number rows
979 prefixStr=[strIndent
' |' filler2
'|'];
981 colIndVec(3:(nRows+1))=numel(prefixStr)+1;
984 varStr = [adjustedFieldValue{iRow,:}];
985 varCell{iRow+1} = [prefixStr varStr];
987 prefixStr=[strIndent
' |' filler2];
989 colIndVec(end)=numel(prefixStr)+1;
991 varCell{nRows+2} = [prefixStr dashes];
994 %% FUNCTION: getIndentation
995 % This
function creates the hierarchical indentations
997 function [str, str2] = getIndentation(indent)
1003 nOuts=numel(outCVec);
1011 outCVec=horzcat(outCVec,cell(1,indent-nOuts));
1012 for iElem = nOuts+1 : indent
1013 str =
cat(2, str, x);
1014 outCVec{iElem} = str;
1017 str = outCVec{indent-1};
1019 str = outCVec{indent-1};
1020 str2 = outCVec{indent};
1025 %% FUNCTION: createArraySize
1026 % This
function returns a
string with the array size of the input variable
1027 % like:
"[1x5 Array]" or
"[2x3x5 Structure]" where
'Structure' and
'Array' 1028 % are defined by the type parameter
1030 function varStr = createArraySize(varName, type)
1031 varSize = size(varName);
1032 arraySizeStr = sprintf(
'%gx', varSize);
1033 arraySizeStr(length(arraySizeStr)) = [];
1034 varStr = [
' [' arraySizeStr
' ' type
']'];
1037 function [isLocalChanges,pathCVec,valCVec]=getleaveslist(SInp,SOld,isFullCheck)
1041 if isequaln(SInp,SOld)
1042 isLocalChanges=
true;
1045 [isLocalChanges,pathCVec]=getleaveslistint(SInp,SOld);
1053 nLeaves=length(pathCVec);
1054 valCVec=cell(nLeaves,1);
1055 for iLeave=1:nLeaves
1056 pathStr=pathCVec{iLeave};
1058 valCVec{iLeave}=eval([
'SInp' pathCVec{iLeave}]);
1060 valCVec{iLeave}=eval([
'SInp.' pathCVec{iLeave}]);
1064 function [isLocalChanges,pathCVec]=getleaveslistint(SInp,SOld,fieldNameList)
1067 if isequaln(SInp,SOld)
1068 isLocalChanges=
true;
1072 fieldNameList=fieldnames(SInp);
1076 oldFieldNameList=fieldnames(SOld);
1077 isLocalChanges=numel(fieldNameList)==numel(oldFieldNameList)&&...
1078 all(
ismember(fieldNameList,oldFieldNameList))&&...
1079 isequal(sizeVec,size(SOld));
1080 if ~isLocalChanges||isempty(SInp)
1085 isLocalChanges=
true;
1089 nFields=numel(fieldNameList);
1090 isLocalChanges=
true;
1094 fieldPathCVec=cell(nFields,nElems);
1100 subIndList=cell(1,length(sizeVec));
1104 [subIndList{:}]=ind2sub(sizeVec,iElem);
1105 indexStr=sprintf(
'%d,',horzcat(subIndList{:}));
1106 indexStr=[
'(' indexStr(1:end-1)
')'];
1108 for iField=1:nFields
1109 fieldName=fieldNameList{iField};
1110 SCur=SInp(iElem).(fieldName);
1111 SOldCur=SOld(iElem).(fieldName);
1112 isCurStruct=isstruct(SCur);
1114 if isCurStruct~=isstruct(SOldCur)
1115 isLocalChanges=
false;
1120 curFieldNameList=fieldnames(SCur);
1121 if ~isempty(curFieldNameList)
1122 [isLocalChanges,fieldPathCVec{iField,iElem}]=...
1123 getleaveslistint(SCur,SOldCur,curFieldNameList);
1127 curFieldPathCVec=fieldPathCVec{iField,iElem};
1128 nPaths=numel(curFieldPathCVec);
1131 prefixStr=horzcat(fieldName,
'.');
1133 prefixStr=fieldName;
1137 prefixStr=horzcat(indexStr,
'.',fieldName,
'.');
1139 prefixStr=horzcat(indexStr,
'.',fieldName);
1143 curFieldPathCVec{iPath}=...
1144 horzcat(prefixStr,curFieldPathCVec{iPath});
1146 fieldPathCVec{iField,iElem}=curFieldPathCVec;
1148 elseif ~isequaln(SCur,SOldCur)
1150 fieldPathCVec{iField,iElem}={fieldName};
1152 fieldPathCVec{iField,iElem}={horzcat(indexStr,
'.',...
1158 pathCVec=vertcat(fieldPathCVec{:});
function num2cell(in inpArray, in varargin)
NUM2CELL is an extension of Matlab built-in function "num2cell" designed to work correctly with empty...
function throwerror(in msgTag, in varargin)
THROWERROR works similarly to built-in ERROR function in case when there is no output arguments but s...
function parseparext(in args, in propNameValMat, in varargin)
PARSEPAREXT behaves in the same way as mxberry.core.parseparams but returns property values in a more...
function repmat(in inpArray, in varargin)
This class is responsible for displaying structure outline.
function isstring(in inpArray)
function ismember(in leftVec, in rightVec, in varargin)
ISMEMBER - ismember implementation for arrays of any type.
function catwithsep(in inpStrList, in sepStr)
CATWITHSEP concatenates input cell array of strings inserting a specified separator between the strin...
function cat(in dimNum, in varargin)