1classdef TaylorSeriesAdaptive < handle
2 properties (Access =
private)
7 dist_in_ref_points = {}
8 norms_in_ref_points = {}
9 derivs_in_ref_points = {}
11 clients_in_ref_points = []
17 function obj = TaylorSeriesAdaptive(proc, pi0, error_value, max_time, approx_type, strategy)
20 approx_type = libqbd.APPROX_TAYLOR_UNLIM();
23 strategy = libqbd.STRATEGY_FAST();
25 obj.bind(proc, pi0, error_value, max_time, approx_type, strategy);
29 function bind(obj, proc, pi0, error_value, max_time, approx_type, strategy)
31 approx_type = libqbd.APPROX_TAYLOR_UNLIM();
34 strategy = libqbd.STRATEGY_FAST();
37 libqbd.raise_error(
'Already binded.');
40 obj.min_elem = -proc.get_min_element();
42 obj.dist_in_ref_points = {pi0};
43 obj.norms_in_ref_points = {{}};
44 obj.derivs_in_ref_points = {{}};
46 obj.error = error_value;
47 obj.max_degree = libqbd.parse_approx_type(approx_type);
48 obj.max_saved_data = min(obj.max_degree,
double(strategy));
49 while obj.ref_points(end) < max_time
50 obj.next_point(libqbd.get_max_factor());
55 function values = get_reference_times(obj)
57 values = obj.ref_points;
60 function values = get_reference_dists(obj)
62 values = obj.dist_in_ref_points;
65 function [dist, errors] = get_dist(obj, times)
73 while obj.ref_points(end) < times(end)
74 obj.next_point(libqbd.get_max_factor());
77 num = obj.find_max_le_t(times(1), 1);
82 reg = (t - obj.ref_points(num)) * obj.min_elem;
84 [dist, errors] = obj.calc_intermed_points(dist, errors, norm_times, num);
86 num = obj.find_max_le_t(t, num);
87 reg = (t - obj.ref_points(num)) * obj.min_elem;
89 norm_times(end + 1) = reg; %#ok<AGROW>
92 if ~isempty(norm_times)
93 [dist, errors] = obj.calc_intermed_points(dist, errors, norm_times, num);
97 function values = get_reference_mean_clients(obj)
99 if numel(obj.clients_in_ref_points) < numel(obj.ref_points)
100 for k = (numel(obj.clients_in_ref_points) + 1):numel(obj.ref_points)
101 obj.clients_in_ref_points(end + 1) = libqbd.function_of_dist(obj.dist_in_ref_points{k}, @client_weights); %#ok<AGROW>
104 values = obj.clients_in_ref_points;
106 function weights = client_weights(level, length)
107 weights = ones(1, length) * level;
112 methods (Access =
private)
115 libqbd.raise_error('Not binded to the process.');
117 if isempty(obj.proc.all_A_0())
118 libqbd.raise_error('Infinitesimal generator matrix
is empty.');
122 function next_point(obj, n)
123 deriv = obj.dist_in_ref_points{end};
129 two_delta_in_n = two_delta_inv;
130 min_elem_inv = 1.0 / obj.min_elem;
132 while er > obj.error && k < n
133 deriv = obj.proc.mull_by_row_vector(deriv, min_elem_inv);
134 res = libqbd.vec_fma(res, deriv, libqbd.get_one_div_by_factor(k));
135 norm_value = libqbd.l1norm_cell(deriv);
136 er = norm_value * gammainc(2.0, k + 2.0,
'lower') * exp(2.0) * two_delta_in_n;
137 if numel(norms) < obj.max_saved_data
138 norms{end + 1} = norm_value; %#ok<AGROW>
139 derivs{end + 1} = deriv; %#ok<AGROW>
141 two_delta_in_n = two_delta_in_n * two_delta_inv;
144 obj.dist_in_ref_points{end + 1} = res;
145 obj.ref_points(end + 1) = obj.ref_points(end) + 1.0 / obj.min_elem;
146 obj.norms_in_ref_points{end + 1} = norms;
147 obj.derivs_in_ref_points{end + 1} = derivs;
150 function [dist, errors] = calc_intermed_points(obj, dist, errors, deltas, num)
153 dist{end + 1} = obj.dist_in_ref_points{num}; %#ok<AGROW>
154 errors(end + 1) = 0.0; %#ok<AGROW>
158 res = obj.dist_in_ref_points{num};
163 delta_minus_n = delta_inv;
165 while k < obj.max_degree && er > obj.error
166 if k < numel(obj.norms_in_ref_points{num})
167 deriv = obj.derivs_in_ref_points{num}{k + 1};
168 norm_value = obj.norms_in_ref_points{num}{k + 1};
170 if isempty(deriv_comp)
171 if ~isempty(obj.derivs_in_ref_points{num})
172 deriv_comp = obj.derivs_in_ref_points{num}{end};
174 deriv_comp = obj.dist_in_ref_points{num};
177 deriv_comp = obj.proc.mull_by_row_vector(deriv_comp, 1.0 / obj.min_elem);
179 norm_value = libqbd.l1norm_cell(deriv_comp);
182 res = libqbd.vec_fma(res, deriv, delta_m * libqbd.get_one_div_by_factor(k));
183 delta_m = delta_m * d;
184 er = norm_value * gammainc(2.0 * d, k + 2.0,
'lower') * exp(2.0 * d) * delta_minus_n;
185 delta_minus_n = delta_minus_n * delta_inv;
188 dist{end + 1} = res; %#ok<AGROW>
189 errors(end + 1) = er; %#ok<AGROW>
193 function num = find_max_le_t(obj, t, num)
194 idx = find(obj.ref_points(num:end) <= t, 1,
'last');