1function [QN, UN, RN, TN, CN, XN, t, QNt, UNt, TNt, xvec_iter, hitprob, missprob, runtime, it] = solver_fld_cacheqn_analyzer(sn, options)
2% SOLVER_FLD_CACHEQN_ANALYZER Fluid solver
for integrated caching-queueing networks
4% Delegates the decomposition-aggregation alternation between the isolated
5% caches and the fluid ODE solution of the surrounding queueing network to
6% da_cacheqn, until the cache arrival rates converge. RANDOM(m) (RR) and
7% FIFO(m) use the refined mean field (cache_miss_rmf, 1/N-accurate; Gast15
8% Thm 1: pi_FIFO(m)=pi_RAND(m)); strict FIFO(m) uses its own position-resolved
9% mean field (cache_miss_sfifo_rmf). LRU/HLRU/CLIMB/QLRU have no drift-based
10% fluid model and are rejected (the FPI characteristic-time approximation
is
11% not a fluid method). Use SolverNC/SolverMVA or SolverLDES
for those.
13% Copyright (c) 2012-2026, Imperial College London
19[res, hitprob, missprob, it, sn] = da_cacheqn(sn, @miss_isolated, @netsolve, options);
20QN = res.QN; UN = res.UN; RN = res.RN; TN = res.TN; XN = res.XN;
21t = res.t; QNt = res.QNt; UNt = res.UNt; TNt = res.TNt; xvec_iter = res.xvec_iter;
27 CN(k) = sn.njobs(k) ./ XN(k);
31% xvec_iter
is already a cell array from solver_fluid_matrix
34 function missrate = miss_isolated(gamma, m, lambda_cache, ch)
35 % RR/FIFO/SFIFO honour a custom access graph (accost) via their general
36 % drift; the linear
default keeps the refined RAND (FIFO) / linear
37 % position-resolved (SFIFO) path. FIFO(m) == RANDOM(m) only
for the
38 % linear chain, so a non-linear graph uses its own position-resolved drift.
39 nonlinear = ~accost_is_linear(ch.accost, length(m));
40 if ch.replacestrat == ReplacementStrategy.RR
41 [~, missrate] = cache_miss_rmf(gamma, m, lambda_cache, [], [], ch.accost);
42 elseif ch.replacestrat == ReplacementStrategy.FIFO
44 [~, missrate] = cache_miss_fifo_rmf(gamma, m, lambda_cache, [], [], ch.accost);
46 [~, missrate] = cache_miss_rmf(gamma, m, lambda_cache);
48 elseif ch.replacestrat == ReplacementStrategy.SFIFO
49 [~, missrate] = cache_miss_sfifo_rmf(gamma, m, lambda_cache, [], [], ch.accost);
51 % LRU/HLRU/CLIMB/QLRU have no drift-based fluid model; the FPI
52 % (characteristic-time) approximation
is not a fluid method. Refuse
53 % rather than substitute a non-fluid fixed point.
54 line_error(mfilename, sprintf([
'SolverFLD supports only ' ...
55 'RANDOM(m)/FIFO(m) (refined mean field) and strict FIFO(m) ' ...
56 '(position-resolved mean field) cache replacement; strategy ' ...
57 '%d has no drift-based fluid model. Use SolverNC/SolverMVA or ' ...
58 'SolverLDES for this cache.'],
double(ch.replacestrat)));
62 function tf = accost_is_linear(accost, h)
63 % True when every per-(user,item) access graph
is the linear chain
64 % (miss -> list 1, hit in list a -> list a+1, self-loop on top list).
68 lin = zeros(h+1, h+1); lin(1,2) = 1;
69 for a = 1:(h-1), lin(a+1, a+2) = 1; end
72 [uu, nn] = size(accost);
76 if isempty(g),
continue; end
77 if ~all(all(abs(g - lin) < 1e-9))
84 function res = netsolve(snit)
85 % Solve the queueing network using the fluid matrix method
87 fluid_options = options;
88 fluid_options.method = 'matrix';
89 fluid_options.init_sol = solver_fluid_initsol(snit, fluid_options);
90 [res.QN, res.UN, res.RN, res.TN, res.xvec_iter, res.QNt, res.UNt, res.TNt, ~, res.t] = solver_fluid_matrix(snit, fluid_options);
92 % Compute system throughputs
95 if snit.refstat(k) > 0
96 res.XN(k) = res.TN(snit.refstat(k), k);