LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
matlab_ilt_matrix.m
1function vals = matlab_ilt_matrix(fun, T, maxFnEvals, method)
2%MATLAB_ILT_MATRIX Numerical inverse Laplace transform of a matrix-valued function.
3% VALS = MATLAB_ILT_MATRIX(FUN, T, MAXFNEVALS, METHOD) inverts the
4% matrix-valued Laplace transform FUN (a handle s -> matrix) at the time
5% points in T, using the Abate-Whitt framework with the same eta/beta weights
6% as the scalar MATLAB_ILT. This variant evaluates FUN once per node and
7% accumulates the full matrix, avoiding one scalar inversion per entry.
8%
9% METHOD is one of 'cme' (default), 'euler', or 'gaver'. Returns a
10% numel(T) x nr x nc array where [nr,nc] = size(FUN(.)).
11%
12% The CME parameter table is loaded from iltcme.json in this folder (shared
13% with MATLAB_ILT).
14if nargin < 4 || isempty(method); method = 'cme'; end
15
16persistent cmeParamsMat cmeParamsMatPath
17here = fileparts(mfilename('fullpath'));
18jsonPath = fullfile(here, 'iltcme.json');
19
20switch lower(method)
21 case 'cme'
22 if isempty(cmeParamsMat) || ~strcmp(cmeParamsMatPath, jsonPath)
23 cmeParamsMat = jsondecode(fileread(jsonPath));
24 cmeParamsMatPath = jsonPath;
25 end
26 params = cmeParamsMat(1);
27 for i = 2:length(cmeParamsMat)
28 if cmeParamsMat(i).cv2 < params.cv2 && (cmeParamsMat(i).n + 1) <= maxFnEvals
29 params = cmeParamsMat(i);
30 end
31 end
32 a = params.a(:);
33 b = params.b(:);
34 c = params.c;
35 mu1 = params.mu1;
36 omega = params.omega;
37 nn = params.n;
38 eta = [c * mu1; (a + 1i*b) * mu1];
39 beta = [1; 1 + 1i * omega * (1:nn).'] * mu1;
40 case 'euler'
41 n_euler = floor((maxFnEvals-1)/2);
42 eta = [0.5, ones(1, n_euler), zeros(1, n_euler-1), 2^-n_euler];
43 for k = 1:n_euler-1
44 eta(2*n_euler-k + 1) = eta(2*n_euler-k + 2) + ...
45 exp(sum(log(1:n_euler)) - n_euler*log(2) - sum(log(1:k)) - sum(log(1:(n_euler-k))));
46 end
47 kidx = 0:2*n_euler;
48 beta = n_euler*log(10)/3 + 1i*pi*kidx;
49 eta = (10^((n_euler)/3))*(1-mod(kidx, 2)*2) .* eta;
50 eta = eta(:); beta = beta(:);
51 case 'gaver'
52 if mod(maxFnEvals,2)==1
53 maxFnEvals = maxFnEvals - 1;
54 end
55 ndiv2 = maxFnEvals/2;
56 eta = zeros(maxFnEvals,1);
57 beta = zeros(maxFnEvals,1);
58 for k = 1:maxFnEvals
59 inside_sum = 0.0;
60 for j = floor((k+1)/2):min(k,ndiv2)
61 inside_sum = inside_sum + exp((ndiv2+1)*log(j) - sum(log(1:(ndiv2-j))) + ...
62 sum(log(1:2*j)) - 2*sum(log(1:j)) - sum(log(1:(k-j))) - sum(log(1:(2*j-k))));
63 end
64 eta(k) = log(2.0)*(-1)^(k+ndiv2)*inside_sum;
65 beta(k) = k * log(2.0);
66 end
67 otherwise
68 line_error(mfilename, sprintf('Unknown inverse Laplace method "%s". Supported: cme, euler, gaver', method));
69end
70
71% Probe output size with one cheap evaluation.
72x0 = T(1);
73M0 = fun(beta(1) / x0);
74[nr, nc] = size(M0);
75
76vals = zeros(numel(T), nr, nc);
77nBeta = numel(eta);
78for ii = 1:numel(T)
79 x = T(ii);
80 acc = zeros(nr, nc);
81 for k = 1:nBeta
82 acc = acc + eta(k) * fun(beta(k) / x);
83 end
84 vals(ii, :, :) = real(acc) / x;
85end
86end
Definition Station.m:245