LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
sn_print.m
1%{ @file sn_print.m
2 % @brief Prints comprehensive information about a NetworkStruct object
3 %
4 % @author LINE Development Team
5%}
6
7%{
8 % @brief Prints comprehensive information about a NetworkStruct object
9 %
10 % @details
11 % This function displays all fields, matrices, lists, and maps in a formatted
12 % manner useful for debugging and inspection of network structures.
13 %
14 % @par Syntax:
15 % @code
16 % sn_print(sn)
17 % @endcode
18 %
19 % @par Parameters:
20 % <table>
21 % <tr><th>Name<th>Description
22 % <tr><td>sn<td>Network structure to inspect
23 % </table>
24%}
25function sn_print(sn)
26
27% Suppress warnings about struct on objects
28warning('off', 'MATLAB:structOnObject');
29
30% Basic integer fields
31fprintf('nstations: %d\n', sn.nstations);
32fprintf('nstateful: %d\n', sn.nstateful);
33fprintf('nnodes: %d\n', sn.nnodes);
34fprintf('nclasses: %d\n', sn.nclasses);
35fprintf('nclosedjobs: %d\n', sn.nclosedjobs);
36fprintf('nchains: %d\n', sn.nchains);
37
38% All matrix fields
39printMatrix('refstat', sn.refstat);
40printMatrix('njobs', sn.njobs);
41printMatrix('nservers', sn.nservers);
42printMatrix('connmatrix', sn.connmatrix);
43printMatrix('scv', sn.scv);
44printMatrix('isstation', sn.isstation);
45printMatrix('isstateful', sn.isstateful);
46printMatrix('isstatedep', sn.isstatedep);
47printMatrix('nodeToStateful', sn.nodeToStateful);
48printMatrix('nodeToStation', sn.nodeToStation);
49printMatrix('stationToNode', sn.stationToNode);
50printMatrix('stationToStateful', sn.stationToStateful);
51printMatrix('statefulToStation', sn.statefulToStation);
52printMatrix('statefulToNode', sn.statefulToNode);
53printMatrix('rates', sn.rates);
54printMatrix('classprio', sn.classprio);
55printMatrix('phases', sn.phases);
56printMatrix('phasessz', sn.phasessz);
57printMatrix('phaseshift', sn.phaseshift);
58printMatrix('schedparam', sn.schedparam);
59printMatrix('chains', sn.chains);
60printMatrix('rt', sn.rt);
61printMatrix('nvars', sn.nvars);
62printMatrix('rtnodes', sn.rtnodes);
63printMatrix('csmask', sn.csmask);
64printMatrix('isslc', sn.isslc);
65printMatrix('cap', sn.cap);
66printMatrix('classcap', sn.classcap);
67printMatrix('refclass', sn.refclass);
68printMatrix('lldscaling', sn.lldscaling);
69printMatrix('fj', sn.fj);
70
71% List fields with content
72printNodeTypeList('nodetype', sn.nodetype);
73if isfield(sn, 'classnames')
74 if iscell(sn.classnames)
75 printList('classnames', sn.classnames);
76 else
77 % Handle single string classname
78 fprintf('classnames: ["%s"]\n', sn.classnames);
79 end
80end
81if isfield(sn, 'nodenames')
82 printList('nodenames', sn.nodenames);
83end
84
85% Map fields with detailed contents
86printMapIfExists(sn, 'rtorig');
87%printMapIfExists(sn, 'lst');
88printMapIfExists(sn, 'state');
89printMapIfExists(sn, 'stateprior');
90printMapIfExists(sn, 'space');
91printMapIfExists(sn, 'routing');
92printMapIfExists(sn, 'procid');
93printMapIfExists(sn, 'mu');
94printMapIfExists(sn, 'phi');
95printMapIfExists(sn, 'proc');
96printMapIfExists(sn, 'pie');
97printMapIfExists(sn, 'sched');
98printMapIfExists(sn, 'inchain');
99printMapIfExists(sn, 'visits');
100printMapIfExists(sn, 'nodevisits');
101printMapIfExists(sn, 'droprule');
102printMapIfExists(sn, 'nodeparam');
103% Special handling for sync field to avoid duplicate printing
104if isfield(sn, 'sync')
105 fprintf('sync: ');
106 value = sn.sync;
107 if iscell(value)
108 % sync is a cell array of sync objects
109 fprintf('{');
110 for i = 1:length(value)
111 if i > 1
112 fprintf(', ');
113 end
114 fprintf('%d: ', i-1); % 0-based index
115
116 syncObj = value{i};
117 if isstruct(syncObj) && isfield(syncObj, 'active') && isfield(syncObj, 'passive')
118 fprintf('{');
119 % Print active events with indices
120 fprintf('"active": {');
121 if iscell(syncObj.active)
122 for j = 1:length(syncObj.active)
123 if j > 1
124 fprintf(', ');
125 end
126 fprintf('%d: ', j-1); % 0-based index
127 printValue(syncObj.active{j});
128 end
129 else
130 fprintf('0: ');
131 printValue(syncObj.active);
132 end
133 fprintf('}');
134
135 % Print passive events with indices
136 fprintf(', "passive": {');
137 if iscell(syncObj.passive)
138 for j = 1:length(syncObj.passive)
139 if j > 1
140 fprintf(', ');
141 end
142 fprintf('%d: ', j-1); % 0-based index
143 printValue(syncObj.passive{j});
144 end
145 else
146 fprintf('0: ');
147 printValue(syncObj.passive);
148 end
149 fprintf('}');
150 fprintf('}');
151 else
152 printValue(syncObj);
153 end
154 end
155 fprintf('}\n');
156 elseif isstruct(value)
157 % Check if it's a map of sync objects
158 fields = fieldnames(value);
159 if ~isempty(fields)
160 fprintf('{');
161 for i = 1:length(fields)
162 if i > 1
163 fprintf(', ');
164 end
165 key = fields{i};
166 % Handle numeric keys like x0, x1
167 if regexp(key, '^x\d+$')
168 fprintf('%s', key(2:end));
169 else
170 fprintf('"%s"', key);
171 end
172 fprintf(': ');
173
174 syncObj = value.(key);
175 if isstruct(syncObj) && isfield(syncObj, 'active') && isfield(syncObj, 'passive')
176 fprintf('{');
177 % Print active events with indices
178 fprintf('"active": {');
179 if iscell(syncObj.active)
180 for j = 1:length(syncObj.active)
181 if j > 1
182 fprintf(', ');
183 end
184 fprintf('%d: ', j-1); % 0-based index
185 printValue(syncObj.active{j});
186 end
187 else
188 fprintf('0: ');
189 printValue(syncObj.active);
190 end
191 fprintf('}');
192
193 % Print passive events with indices
194 fprintf(', "passive": {');
195 if iscell(syncObj.passive)
196 for j = 1:length(syncObj.passive)
197 if j > 1
198 fprintf(', ');
199 end
200 fprintf('%d: ', j-1); % 0-based index
201 printValue(syncObj.passive{j});
202 end
203 else
204 fprintf('0: ');
205 printValue(syncObj.passive);
206 end
207 fprintf('}');
208 fprintf('}');
209 else
210 printValue(syncObj);
211 end
212 end
213 fprintf('}\n');
214 else
215 fprintf('{}\n');
216 end
217 else
218 printValue(value);
219 fprintf('\n');
220 end
221else
222 % Field doesn't exist, skip
223end
224printMapIfExists(sn, 'gsync');
225printMapIfExists(sn, 'cdscaling');
226
227% Restore warnings
228warning('on', 'MATLAB:structOnObject');
229
230end
231
232function matStr = printMatrixCompact(matrix)
233% Helper function to print matrix in compact format for maps
234if isempty(matrix)
235 matStr = '[]';
236 return;
237end
238
239sb = '[';
240[numRows, numCols] = size(matrix);
241for i = 1:numRows
242 if i > 1
243 sb = [sb '; '];
244 end
245 for j = 1:numCols
246 if j > 1
247 sb = [sb ' '];
248 end
249 value = matrix(i, j);
250 % Check if matrix contains only integers or if individual value is integer
251 if (isnumeric(matrix) && all(matrix(:) == floor(matrix(:))) && all(~isinf(matrix(:)))) || ...
252 (value == floor(value) && ~isinf(value))
253 sb = [sb num2str(round(value))];
254 else
255 sb = [sb num2str(value)];
256 end
257 end
258end
259sb = [sb ']'];
260matStr = sb;
261end
262
263function printNodeTypeList(name, nodeTypes)
264% Helper function to print nodetype array with proper formatting
265fprintf('%s: ', name);
266if isempty(nodeTypes)
267 fprintf('[]\n');
268else
269 fprintf('[');
270 for i = 1:length(nodeTypes)
271 if i > 1
272 fprintf(', ');
273 end
274 fprintf('%s', NodeType.toText(nodeTypes(i)));
275 end
276 fprintf(']\n');
277end
278end
279
280function printList(name, list)
281% Helper function to print lists with proper formatting
282fprintf('%s: ', name);
283if isempty(list)
284 fprintf('[]\n');
285elseif iscell(list)
286 fprintf('[');
287 for i = 1:length(list)
288 if i > 1
289 fprintf(', ');
290 end
291 if ischar(list{i}) || isstring(list{i})
292 fprintf('"%s"', char(list{i}));
293 else
294 fprintf('%s', mat2str(list{i}));
295 end
296 end
297 fprintf(']\n');
298elseif isnumeric(list)
299 % Handle numeric arrays
300 fprintf('%s\n', printMatrixCompact(list));
301else
302 % Handle other types
303 fprintf('%s\n', mat2str(list));
304end
305end
306
307function printMatrix(name, matrix)
308% Helper function to print matrix with all values
309if isempty(matrix)
310 fprintf('%s: []\n', name);
311elseif isnumeric(matrix) && all(isnan(matrix(:)))
312 fprintf('%s: null\n', name);
313else
314 fprintf('%s: %s\n', name, printMatrixCompact(matrix));
315end
316end
317
318function printMapIfExists(sn, fieldName)
319% Helper function to print fields only if they exist
320if isfield(sn, fieldName)
321 value = sn.(fieldName);
322 if isstruct(value)
323 printMapContents(fieldName, value);
324 elseif iscell(value)
325 printCellContents(fieldName, value);
326 else
327 % For other types, use printMatrix
328 printMatrix(fieldName, value);
329 end
330end
331end
332
333function printCellContents(name, cellArray)
334% Helper function to print cell array contents
335fprintf('%s: ', name);
336if isempty(cellArray)
337 fprintf('{}\n');
338else
339 % Check if this is a single-element cell array containing a matrix
340 if numel(cellArray) == 1 && isnumeric(cellArray{1})
341 % Just print the matrix directly without extra brackets
342 fprintf('%s\n', printMatrixCompact(cellArray{1}));
343 return;
344 end
345
346 % Check if this is a map-like cell array
347 if numel(cellArray) > 0 && isstruct(cellArray{1})
348 % Print as a map
349 printMapContents(name, cellArray{1});
350 return;
351 end
352
353 % Special handling for certain fields that are map-like
354 if strcmp(name, 'state') || strcmp(name, 'stateprior') || strcmp(name, 'space') || ...
355 strcmp(name, 'mu') || strcmp(name, 'phi') || strcmp(name, 'pie')
356 % These fields use station names as keys
357 fprintf('{');
358 % Assume we have access to station names through evalin
359 try
360 nodenames = evalin('caller', 'sn.nodenames');
361 for i = 1:numel(cellArray)
362 if i > 1
363 fprintf(', ');
364 end
365 if i <= length(nodenames)
366 fprintf('"%s": ', nodenames{i});
367 end
368 printValue(cellArray{i});
369 end
370 catch
371 % Fall back to simple array printing
372 for i = 1:numel(cellArray)
373 if i > 1
374 fprintf(', ');
375 end
376 printValue(cellArray{i});
377 end
378 end
379 fprintf('}\n');
380 else
381 % Regular cell array - use [] for arrays
382 fprintf('[');
383 for i = 1:numel(cellArray)
384 if i > 1
385 fprintf(', ');
386 end
387 printValue(cellArray{i});
388 end
389 fprintf(']\n');
390 end
391end
392end
393
394function printMapContents(name, mapStruct)
395% Helper function to print map contents with detailed structure
396if isempty(mapStruct) || ~exist('mapStruct', 'var')
397 if ~isempty(name)
398 fprintf('%s: null\n', name);
399 else
400 fprintf('null\n');
401 end
402 return;
403end
404
405if ~isstruct(mapStruct)
406 if ~isempty(name)
407 fprintf('%s: null\n', name);
408 else
409 fprintf('null\n');
410 end
411 return;
412end
413
414fields = fieldnames(mapStruct);
415if isempty(fields)
416 if ~isempty(name)
417 fprintf('%s: {}\n', name);
418 else
419 fprintf('{}\n');
420 end
421 return;
422end
423
424if ~isempty(name)
425 fprintf('%s: {', name);
426else
427 fprintf('{');
428end
429first = true;
430for i = 1:length(fields)
431 if ~first
432 fprintf(', ');
433 end
434 first = false;
435
436 % Print key - handle different key types like the Kotlin version
437 key = fields{i};
438 % Check if key is numeric (like x0, x1, etc.)
439 if regexp(key, '^x\d+$')
440 % Extract the numeric part
441 fprintf('%s', key(2:end));
442 elseif ischar(key)
443 fprintf('"%s"', key);
444 else
445 fprintf('"%s"', char(string(key)));
446 end
447
448 fprintf(': ');
449
450 % Print value
451 value = mapStruct.(key);
452 printValue(value);
453end
454fprintf('}\n');
455end
456
457function printValue(value)
458% Helper function to print individual values with appropriate formatting
459if isempty(value)
460 fprintf('null');
461elseif isa(value, 'jline.lang.Event') || (isjava(value) && contains(class(value), 'Event'))
462 % Handle Java Event objects
463 fprintf('{');
464 printed = false;
465
466 % Try to print each field
467 try
468 nodeVal = value.getNode();
469 fprintf('"node": %d', nodeVal);
470 printed = true;
471 catch
472 % Can't get node
473 end
474
475 try
476 eventVal = value.getEvent();
477 if printed
478 fprintf(', ');
479 end
480 fprintf('"event": ');
481 try
482 fprintf('%d', eventVal.getId());
483 catch
484 fprintf('"%s"', char(eventVal.toString()));
485 end
486 printed = true;
487 catch
488 % Can't get event
489 end
490
491 try
492 classVal = value.getJobClass();
493 if printed
494 fprintf(', ');
495 end
496 fprintf('"class": %d', classVal);
497 printed = true;
498 end
499
500 try
501 probVal = value.getProb();
502 if printed
503 fprintf(', ');
504 end
505 fprintf('"prob": ');
506 if isnan(probVal)
507 fprintf('NaN');
508 else
509 fprintf('%g', probVal);
510 end
511 printed = true;
512 catch
513 % Skip prob
514 end
515
516 try
517 stateVal = value.getState();
518 if printed
519 fprintf(', ');
520 end
521 fprintf('"state": ');
522 if isempty(stateVal) || (isa(stateVal, 'jline.util.matrix.Matrix') && stateVal.isEmpty())
523 fprintf('[]');
524 else
525 printValue(stateVal);
526 end
527 printed = true;
528 catch
529 % Skip state
530 end
531
532 try
533 tVal = value.getT();
534 if printed
535 fprintf(', ');
536 end
537 fprintf('"t": ');
538 if isnan(tVal)
539 fprintf('NaN');
540 else
541 fprintf('%g', tVal);
542 end
543 printed = true;
544 catch
545 % Skip t
546 end
547
548 try
549 jobVal = value.getJob();
550 if printed
551 fprintf(', ');
552 end
553 fprintf('"job": ');
554 if isnan(jobVal)
555 fprintf('NaN');
556 else
557 fprintf('%g', jobVal);
558 end
559 printed = true;
560 catch
561 % Skip job
562 end
563
564 % If nothing was printed, show it's an Event
565 if ~printed
566 fprintf('<Event>');
567 end
568
569 fprintf('}');
570elseif isstruct(value)
571 fields = fieldnames(value);
572 if isempty(fields)
573 % Check if this might be a Java object that appears as empty struct
574 className = class(value);
575 if contains(className, 'Event')
576 fprintf('{<Event object - fields not accessible>}');
577 else
578 fprintf('{}');
579 end
580 else
581 fprintf('{');
582 for i = 1:length(fields)
583 if i > 1
584 fprintf(', ');
585 end
586 fprintf('"%s": ', fields{i});
587 printValue(value.(fields{i}));
588 end
589 fprintf('}');
590 end
591elseif isnumeric(value)
592 if numel(value) > 1
593 fprintf('%s', printMatrixCompact(value));
594 else
595 if value == floor(value) && ~isinf(value)
596 fprintf('%d', round(value));
597 else
598 fprintf('%g', value);
599 end
600 end
601elseif ischar(value) || isstring(value)
602 fprintf('"%s"', char(value));
603elseif islogical(value)
604 if value
605 fprintf('true');
606 else
607 fprintf('false');
608 end
609elseif iscell(value)
610 % Check if this is a nested cell array (like proc field)
611 if numel(value) > 0 && iscell(value{1})
612 % Handle nested cell array as indexed map
613 fprintf('{');
614 for i = 1:numel(value)
615 if i > 1
616 fprintf(', ');
617 end
618 fprintf('[%d]: ', i-1); % Use 0-based indexing for consistency with Java
619 printValue(value{i});
620 end
621 fprintf('}');
622 else
623 % Regular cell array
624 fprintf('[');
625 for i = 1:length(value)
626 if i > 1
627 fprintf(', ');
628 end
629 printValue(value{i});
630 end
631 fprintf(']');
632 end
633elseif isa(value, 'function_handle')
634 % Display function handles similar to Java lambda notation
635 funcStr = func2str(value);
636 if contains(funcStr, '@')
637 funcStr = strrep(funcStr, '@', '');
638 end
639 fprintf('%s', funcStr);
640else
641 % Handle objects and other types
642 try
643 % Check if it's a Sync object
644 if isa(value, 'Sync')
645 fprintf('{');
646 fprintf('"active": ');
647 printValue(value.active);
648 fprintf(', "passive": ');
649 printValue(value.passive);
650 fprintf('}');
651 else
652 str = char(string(value));
653 % Check if this is a sync string that needs special handling
654 if contains(str, 'sync:')
655 % This is likely the sync field being printed as a string
656 % Extract the content after "sync:"
657 syncContent = strtrim(extractAfter(str, 'sync:'));
658 fprintf('%s', syncContent);
659 elseif contains(str, 'x') && contains(str, ' ')
660 % Clean up MATLAB object notation (e.g., 1x1 ClosedClass)
661 parts = split(str, ' ');
662 if length(parts) >= 2
663 fprintf('%s', parts{end});
664 else
665 fprintf('%s', str);
666 end
667 else
668 fprintf('%s', str);
669 end
670 end
671 catch
672 % If conversion fails, just display the class name
673 fprintf('<%s>', class(value));
674 end
675end
676end