LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
lqn_bpmn_debug2.m
1% More detailed debug to trace numerical explosion in lqn_bpmn
2clear solver AvgTable
3fprintf(1,'DEBUG: Tracing numerical explosion in lqn_bpmn model\n\n');
4
5model = LayeredNetwork('myLayeredModel');
6
7P{1} = Processor(model, 'R1_Processor', 100, SchedStrategy.FCFS);
8P{2} = Processor(model, 'R2_Processor', Inf, SchedStrategy.INF);
9P{3} = Processor(model, 'R3_Processor', 2, SchedStrategy.FCFS);
10P{4} = Processor(model, 'R1A_Processor', 7, SchedStrategy.FCFS);
11P{5} = Processor(model, 'R1B_Processor', 3, SchedStrategy.FCFS);
12P{6} = Processor(model, 'R2A_Processor', 4, SchedStrategy.FCFS);
13P{7} = Processor(model, 'R2B_Processor', 5, SchedStrategy.FCFS);
14
15T{1} = Task(model, 'R1_Task', 100, SchedStrategy.REF).on(P{1}).setThinkTime(Exp.fitMean(20));
16T{2} = Task(model, 'R2_Task', Inf, SchedStrategy.INF).on(P{2}).setThinkTime(Immediate());
17T{3} = Task(model, 'R3_Task', 2, SchedStrategy.FCFS).on(P{3}).setThinkTime(Immediate());
18T{4} = Task(model, 'R1A_Task', 7, SchedStrategy.FCFS).on(P{4}).setThinkTime(Immediate());
19T{5} = Task(model, 'R1B_Task', 3, SchedStrategy.FCFS).on(P{5}).setThinkTime(Immediate());
20T{6} = Task(model, 'R2A_Task', 4, SchedStrategy.FCFS).on(P{6}).setThinkTime(Immediate());
21T{7} = Task(model, 'R2B_Task', 5, SchedStrategy.FCFS).on(P{7}).setThinkTime(Immediate());
22
23E{1} = Entry(model, 'R1_Ref_Entry').on(T{1});
24E{2} = Entry(model, 'R2_Synch_A2_Entry').on(T{2});
25E{3} = Entry(model, 'R2_Synch_A5_Entry').on(T{2});
26E{4} = Entry(model, 'R3_Synch_A9_Entry').on(T{3});
27E{5} = Entry(model, 'R1A_Synch_A1_Entry').on(T{4});
28E{6} = Entry(model, 'R1A_Synch_A2_Entry').on(T{4});
29E{7} = Entry(model, 'R1A_Synch_A3_Entry').on(T{4});
30E{8} = Entry(model, 'R1B_Synch_A4_Entry').on(T{5});
31E{9} = Entry(model, 'R1B_Synch_A5_Entry').on(T{5});
32E{10} = Entry(model, 'R1B_Synch_A6_Entry').on(T{5});
33E{11} = Entry(model, 'R2A_Synch_A7_Entry').on(T{6});
34E{12} = Entry(model, 'R2A_Synch_A8_Entry').on(T{6});
35E{13} = Entry(model, 'R2A_Synch_A11_Entry').on(T{6});
36E{14} = Entry(model, 'R2B_Synch_A9_Entry').on(T{7});
37E{15} = Entry(model, 'R2B_Synch_A10_Entry').on(T{7});
38E{16} = Entry(model, 'R2B_Synch_A12_Entry').on(T{7});
39
40A{1} = Activity(model, 'A1_Empty', Immediate()).on(T{1}).boundTo(E{1}).synchCall(E{5},1);
41A{2} = Activity(model, 'A2_Empty', Immediate()).on(T{1}).synchCall(E{6},1);
42A{3} = Activity(model, 'A5_Empty', Immediate()).on(T{1}).synchCall(E{9},1);
43A{4} = Activity(model, 'A6_Empty', Immediate()).on(T{1}).synchCall(E{10},1);
44A{5} = Activity(model, 'A3_Empty', Immediate()).on(T{1}).synchCall(E{7},1);
45A{6} = Activity(model, 'A4_Empty', Immediate()).on(T{1}).synchCall(E{8},1);
46A{7} = Activity(model, 'E4_Empty', Immediate()).on(T{2}).boundTo(E{2});
47A{8} = Activity(model, 'A7_Empty', Immediate()).on(T{2}).synchCall(E{11},1);
48A{9} = Activity(model, 'A8_Empty', Immediate()).on(T{2}).synchCall(E{12},1);
49A{10} = Activity(model, 'A9_Empty', Immediate()).on(T{2}).synchCall(E{14},1);
50A{11} = Activity(model, 'A11_Empty', Immediate()).on(T{2}).synchCall(E{13},1).repliesTo(E{2});
51A{12} = Activity(model, 'A12_Empty', Immediate()).on(T{2}).boundTo(E{3}).synchCall(E{16},1).repliesTo(E{3});
52A{13} = Activity(model, 'A10_Empty', Immediate()).on(T{2}).synchCall(E{15},1);
53A{14} = Activity(model, 'A13', Exp.fitMean(10)).on(T{3}).boundTo(E{4}).repliesTo(E{4});
54A{15} = Activity(model, 'A1', Exp.fitMean(7)).on(T{4}).boundTo(E{5}).repliesTo(E{5});
55A{16} = Activity(model, 'A2', Exp.fitMean(4)).on(T{4}).boundTo(E{6});
56A{17} = Activity(model, 'A3', Exp.fitMean(5)).on(T{4}).boundTo(E{7}).repliesTo(E{7});
57A{18} = Activity(model, 'A2_Res_Empty', Immediate()).on(T{4}).synchCall(E{2},1).repliesTo(E{6});
58A{19} = Activity(model, 'A4', Exp.fitMean(8)).on(T{5}).boundTo(E{8}).repliesTo(E{8});
59A{20} = Activity(model, 'A5', Exp.fitMean(4)).on(T{5}).boundTo(E{9});
60A{21} = Activity(model, 'A6', Exp.fitMean(6)).on(T{5}).boundTo(E{10}).repliesTo(E{10});
61A{22} = Activity(model, 'A5_Res_Empty', Immediate()).on(T{5}).synchCall(E{3},1).repliesTo(E{9});
62A{23} = Activity(model, 'A7', Exp.fitMean(6)).on(T{6}).boundTo(E{11}).repliesTo(E{11});
63A{24} = Activity(model, 'A8', Exp.fitMean(8)).on(T{6}).boundTo(E{12}).repliesTo(E{12});
64A{25} = Activity(model, 'A11', Exp.fitMean(4)).on(T{6}).boundTo(E{13}).repliesTo(E{13});
65A{26} = Activity(model, 'A9', Exp.fitMean(4)).on(T{7}).boundTo(E{14});
66A{27} = Activity(model, 'A10', Exp.fitMean(6)).on(T{7}).boundTo(E{15}).repliesTo(E{15});
67A{28} = Activity(model, 'A12', Exp.fitMean(8)).on(T{7}).boundTo(E{16}).repliesTo(E{16});
68A{29} = Activity(model, 'A9_Res_Empty', Immediate()).on(T{7}).synchCall(E{4},1).repliesTo(E{14});
69
70T{1}.addPrecedence(ActivityPrecedence.Serial(A{1}, A{2}));
71T{1}.addPrecedence(ActivityPrecedence.Serial(A{3}, A{4}));
72T{2}.addPrecedence(ActivityPrecedence.Serial(A{7}, A{8}));
73T{2}.addPrecedence(ActivityPrecedence.Serial(A{10}, A{13}));
74T{4}.addPrecedence(ActivityPrecedence.Serial(A{16}, A{18}));
75T{5}.addPrecedence(ActivityPrecedence.Serial(A{20}, A{22}));
76T{7}.addPrecedence(ActivityPrecedence.Serial(A{26}, A{29}));
77T{1}.addPrecedence(ActivityPrecedence.OrFork(A{2},{A{5}, A{6}},[0.6,0.4]));
78T{2}.addPrecedence(ActivityPrecedence.AndFork(A{8},{A{9}, A{10}}));
79T{1}.addPrecedence(ActivityPrecedence.OrJoin({A{5}, A{6}}, A{3}));
80T{2}.addPrecedence(ActivityPrecedence.AndJoin({A{9}, A{13}}, A{11}));
81
82% Create solver
83lnoptions = LN.defaultOptions;
84lnoptions.verbose = 0;
85lnoptions.iter_max = 10; % Limit to see the explosion clearly
86
87options = MVA.defaultOptions;
88options.verbose = 0;
89
90solver = LN(model, @(model) MVA(model, options), lnoptions);
91
92% Manually iterate to trace the explosion
93solver.init();
94
95fprintf(1,'=== Starting manual iteration ===\n\n');
96
97for it = 1:10
98 fprintf(1,'\n========== ITERATION %d ==========\n', it);
99
100 solver.pre(it);
101
102 % Analyze each layer
103 for e = 1:solver.nlayers
104 [results{it,e}, ~] = solver.analyze(it, e);
105
106 % Check for explosion in this layer
107 if ~isempty(results{it,e})
108 maxQN = max(results{it,e}.QN(:));
109 maxTN = max(results{it,e}.TN(:));
110 maxRN = max(results{it,e}.RN(:));
111 if maxQN > 1e6 || maxRN > 1e6
112 fprintf(1,'*** EXPLOSION DETECTED: Layer %d, Iter %d: max(QN)=%.6e, max(RN)=%.6e\n', ...
113 e, it, maxQN, maxRN);
114
115 % Print layer details
116 fprintf(1,'Layer %d structure:\n', e);
117 fprintf(1,' Number of jobs: %s\n', mat2str(solver.ensemble{e}.getNumberOfJobs));
118
119 % Print service demands for each class
120 for c = 1:solver.ensemble{e}.getNumberOfClasses
121 cls = solver.ensemble{e}.classes{c};
122 fprintf(1,' Class %d (%s): ', c, cls.name);
123
124 % Get service time at server
125 serverIdx = solver.ensemble{e}.attribute.serverIdx;
126 node = solver.ensemble{e}.nodes{serverIdx};
127 if ~isempty(node.serviceProcess) && c <= length(node.serviceProcess)
128 proc = node.serviceProcess{c};
129 if ~isempty(proc) && ~isempty(proc{end})
130 fprintf(1,'servt=%.6e ', proc{end}.getMean());
131 end
132 end
133 fprintf(1,'\n');
134 end
135 end
136 end
137 end
138
139 solver.results = results;
140 solver.post(it);
141
142 % Print key servt values after post
143 fprintf(1,'\nAfter post(): key servt values:\n');
144 lqn = solver.lqn;
145 for eidx = (lqn.eshift+1):(lqn.eshift+min(5,lqn.nentries))
146 fprintf(1,' Entry %d servt=%.6e\n', eidx-lqn.eshift, solver.servt(eidx));
147 end
148
149 % Check for explosion in servt
150 maxServt = max(solver.servt(:));
151 if maxServt > 1e6
152 fprintf(1,'*** servt EXPLOSION: max(servt)=%.6e\n', maxServt);
153 [val, idx] = max(solver.servt(:));
154 fprintf(1,' at index %d\n', idx);
155 end
156
157 % Check convergence
158 if solver.converged(it)
159 fprintf(1,'Converged at iteration %d\n', it);
160 break;
161 end
162end
163
164fprintf(1,'\n=== Final servt values ===\n');
165for eidx = (lqn.eshift+1):(lqn.eshift+lqn.nentries)
166 fprintf(1,'Entry %d: servt=%.6e\n', eidx-lqn.eshift, solver.servt(eidx));
167end