1function [W_red, state_map] = eliminate_immediate_matrix(W, sn, options)
2% [W_RED, STATE_MAP] = ELIMINATE_IMMEDIATE_MATRIX(W, SN, OPTIONS)
4% Eliminate immediate states from infinitesimal generator matrix W
7% W: [n_states x n_states] infinitesimal generator matrix
9% options: Solver options
12% W_red: Reduced generator matrix
13% state_map: Mapping from reduced to original state indices
15% Copyright (c) 2012-2026, Imperial College London
18% Get immediate detection threshold
19if isfield(options.config,
'immediate_tol')
20 imm_tol = options.config.immediate_tol;
22 imm_tol = GlobalConstants.Immediate / 10; % Default: 1e7
25% Identify immediate states (those with very high outgoing rates)
26max_rate_per_state = max(abs(W), [], 2);
27imm_states = find(max_rate_per_state >= imm_tol);
29% If no immediate states, return unchanged
32 state_map = 1:size(W, 1);
36% Identify timed states
37timed_states = setdiff(1:size(W,1), imm_states);
39% Check that we have some timed states remaining
40if isempty(timed_states)
41 error('LINE:Fluid:AllImmediate', ...
42 'All states have immediate transitions - cannot eliminate');
46 % Apply stochastic complement
47 [W_red, ~, ~, ~, Q22, ~] = ctmc_stochcomp(W, timed_states);
50 if rcond(full(Q22)) < 1e-12
51 warning('LINE:Fluid:IllConditioned', ...
52 'Immediate transition matrix ill-conditioned (rcond = %g)', rcond(full(Q22)));
55 state_map = timed_states;
58 if isfield(options, 'verbose') && options.verbose > 0
59 reduction_pct = 100 * (1 - length(timed_states)/size(W,1));
60 line_printf(sprintf('State space reduced from %d to %d states (%.1f%% reduction)\n', ...
61 size(W,1), length(timed_states), reduction_pct));
65 % Elimination failed - fall back to original
66 warning('LINE:Fluid:EliminationFailed', ...
67 'Immediate transition elimination failed: %s. Using original system.', ME.message);
69 state_map = 1:size(W, 1);
72end % eliminate_immediate_matrix