LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
solver_nc_cacheqn_analyzer.m
1function [QN,UN,RN,TN,CN,XN,lG,hitprob,missprob,runtime,it,method] = solver_nc_cacheqn_analyzer(self, options)
2% [Q,U,R,T,C,X,LG,RUNTIME,ITER] = SOLVER_NC_CACHEQN_ANALYZER(SELF, OPTIONS)
3
4% Copyright (c) 2012-2026, Imperial College London
5% All rights reserved.
6
7snorig = self.model.getStruct;
8sn = snorig;
9I = sn.nnodes;
10K = sn.nclasses;
11
12line_debug('NC cacheqn analyzer starting: method=%s, nclasses=%d', options.method, K);
13
14statefulNodes = find(sn.isstateful)';
15statefulNodesClasses = [];
16for ind=statefulNodes %#ok<FXSET>
17 statefulNodesClasses(end+1:end+K)= ((ind-1)*K+1):(ind*K);
18end
19lambda = zeros(1,K);
20lambda_1 = zeros(1,K);
21caches = find(sn.nodetype == NodeType.Cache);
22
23hitprob = zeros(length(caches),K);
24missprob = zeros(length(caches),K);
25
26for it=1:options.iter_max
27 for ind=caches
28 ch = sn.nodeparam{ind};
29 hitClass = ch.hitclass;
30 missClass = ch.missclass;
31 inputClass = find(hitClass);
32 m = ch.itemcap;
33 n = ch.nitems;
34 if it == 1
35 if n<sum(m)+2
36 line_error(mfilename,'NC requires the number of items to exceed the cache capacity at least by 2.');
37 end
38 % initial random value of arrival rates to the cache
39 lambda_1(inputClass) = rand(1,length(inputClass));
40 lambda = lambda_1;
41 sn.nodetype(ind) = NodeType.ClassSwitch;
42 end
43
44 % solution of isolated cache
45 h = length(m);
46 u = length(lambda);
47 lambda_cache = zeros(u,n,h);
48
49 for v=1:u
50 for k=1:n
51 for l=1:(h+1)
52 if ~isnan(ch.pread{v})
53 lambda_cache(v,k,l) = lambda(v) * ch.pread{v}(k);
54 end
55 end
56 end
57 end
58
59 Rcost = ch.accost;
60 if isempty(Rcost)
61 % Default linear cache routing: items flow from list l to list l+1
62 Rcost = cell(u, n);
63 for v = 1:u
64 for k = 1:n
65 Rmat = diag(ones(1, h), 1);
66 Rmat(h+1, h+1) = 1;
67 Rcost{v, k} = Rmat;
68 end
69 end
70 end
71 gamma = cache_gamma_lp(lambda_cache,Rcost);
72 switch options.method
73 case 'exact'
74 [pij] = cache_prob_erec(gamma, m);
75 missrate(ind,:) = zeros(1,u);
76 for v=1:u
77 missrate(ind,v) = lambda_cache(v,:,1)*pij(:,1);
78 end
79 method = 'exact';
80 otherwise
81 line_debug('Default method: using SPM approximation for cache\n');
82 line_debug('Using SPM approximation, calling cache_miss_spm');
83 [~,missrate(ind,:)] = cache_miss_spm(gamma, m, lambda_cache);
84 method = 'spm';
85 end
86
87 missprob(ind,:) = missrate(ind,:) ./ lambda; % we set to NaN if no arrivals
88 hitprob(ind,:) = 1 - missprob(ind,:);
89 hitprob(isnan(hitprob)) = 0;
90 missprob(isnan(missprob)) = 0;
91
92 % bring back the isolated model results into the queueing model
93 for r=inputClass
94 sn.rtnodes((ind-1)*K+r,:) = 0;
95 for jnd=1:I
96 if sn.connmatrix(ind,jnd)
97 sn.rtnodes((ind-1)*K+r,(jnd-1)*K+hitClass(r)) = hitprob(ind,r);
98 sn.rtnodes((ind-1)*K+r,(jnd-1)*K+missClass(r)) = missprob(ind,r);
99 end
100 end
101 end
102 sn.rt = dtmc_stochcomp(sn.rtnodes,statefulNodesClasses);
103 end
104 [visits, nodevisits, sn] = sn_refresh_visits(sn, sn.chains, sn.rt, sn.rtnodes);
105 sn.visits = visits;
106 sn.nodevisits = nodevisits;
107
108 if ~isempty(sn.lldscaling) || ~isempty(sn.cdscaling)
109 [QN,UN,RN,TN,CN,XN,lG,runtime] = solver_ncld_analyzer(sn, options);
110 else
111 [QN,UN,RN,TN,CN,XN,lG,runtime] = solver_nc_analyzer(sn, options);
112 end
113
114 nodevisits = cellsum(nodevisits);
115 for ind=caches
116 for r=inputClass
117 c = find(sn.chains(:,r));
118 inchain = find(sn.chains(c,:));
119 if sn.refclass(c)>0
120 lambda(r) = sum(XN(inchain)) * nodevisits(ind,r) / nodevisits(sn.stationToNode(sn.refstat(r)),sn.refclass(c));
121 else
122 lambda(r) = sum(XN(inchain)) * nodevisits(ind,r) / nodevisits(sn.stationToNode(sn.refstat(r)),r);
123 end
124 end
125 end
126 if norm(lambda-lambda_1,1) < options.iter_tol
127 break
128 end
129 lambda_1 = lambda;
130end
131end