1function [M2a, M3a, GAMMAa] = amap2_adjust_gamma(M1, M2, M3, GAMMA, weights, method, constraints)
2% Computes a feasible set of characteristics
for the MAP(2) that
is as
3% close as possible to the desired set of characterstics.
5% - M1,M2,M3: moments of the marginal distribution
6% - GAMMA: auto-correlation decay rate
7% - weights: an optional three-element vector with the weights associated
8% to M2, M3, GAMMA. Default
is [10 1 10];
9% - method: the method used to compute the feasible set of characteristics
10% 1) pattern search on M2, M3, GAMMA
11% 2) fit M3 as closely as possible, then perform pattern search
12% on M3, GAMMA (weight of M2
is ignored)
13% 3) (default) prioritize M2, then M3, then GAMMA
14% 4) fit M2 as closely as possible, then perform PSwarm
15% on M3 with bounds [M3_lb(M2), M3_ub(M2)] minimizing the
17% f(x) = weight(2)*(M3a/M3-1)^2 + weight(3)*(GAMMAa/GAMMA-1)^2
18% where GAMMAa = max(GAMMA_LB(M3a), min(GAMMA, GAMMA_UB(M3a))
20% - M2a,M3a: feasible moments of the marginal distribution (M1
is always
22% - GAMMAa: feasible auto-correlation decay rate
24if nargin == 4 || isempty(weights)
25 % ignored with method 3 and 4
38 nonlcon = @nonlcon_safe;
40 nonlcon = @nonlcon_safe2;
42elseif constraints == 2
44 nonlcon = @nonlcon_theoretical;
46 nonlcon = @nonlcon_theoretical2;
49 error('Invalid option');
52if method == 1 || method == 2
54 options = psoptimset(options,'MaxIter', 1e5);
55 options = psoptimset(options,'MaxFunEvals', 1e5);
56 options = psoptimset(options,'PollingOrder', 'Success');
57 options = psoptimset(options,'SearchMethod', { @searchneldermead [] [] });
58 options = psoptimset(options,
'CompleteSearch',
'on');
59 options = psoptimset(options,
'Display',
'iter');
60 options = psoptimset(options,
'TolCon', 1e-100);
63% tolerance
for strict inequalities
68 FEASIBLE = map_scale(amap2_assemble(1,1/3,1/2,2/3,1),M1);
70 FEASIBLE = map_scale(amap2_assemble(1,2/3,1/2,2/3,2),M1);
72 FM2 = map_moment(FEASIBLE,2);
73 FM3 = map_moment(FEASIBLE,3);
74 FGAMMA = map_acf(FEASIBLE,4)/map_acf(FEASIBLE,3);
75 x = patternsearch(@fun,[FM2 FM3 FGAMMA],[],[],[],[],[0 0 -1],[inf inf, 1-tol], nonlcon, options);
80 % force feasibility of the second moment
81 M2a = max(3/2*M1^2, M2);
82 % find a feasible value of the third moment. The interval must be derived
83 % from the ADJUSTED second moment: with the unadjusted M2 the branch test
84 % and the bound formulas below refer to a normalized moment the search
is
85 % not constrained to, which can
return an inverted interval and abort
86 % nonlcon_theoretical2 with a complex constraint value.
88 p2 = 3*(n2-2)/(3*n2) * (-2*sqrt(3)/sqrt(12-6*n2) - 1);
89 a2 = (n2-2)/(p2*(1-n2) + sqrt(p2^2 + (2*p2*(n2-2))));
90 l2 = 3*(a2+1)/(a2*p2+1) - (6*a2)/(2+a2*p2*(2*a2+2));
92 if 3/2 <= n2 && n2 < 2
93 FM3 = (l2 + (u2-l2)/2) * M1* M2a;
94 M3_LB = l2 * M1 * M2a;
95 M3_UB = u2 * M1 * M2a;
97 FM3 = (3/2) * M2a^2 / M1 + tol;
101 % null decay rate
is always feasible
103 % find best feasible values of M3 and GAMMA
104 x = patternsearch(@fun2,[FM3 FGAMMA],[],[],[],[],[M3_LB -1],[M3_UB, 1-tol], nonlcon, options);
105 %x = fmincon(@fun2,[FM3 FGAMMA],[],[],[],[],[M3_LB -1],[M3_UB, 1], nonlcon);
109 % priorities are M2 > M3 > GAMMA
110 [M2a,M3a] = aph2_adjust(M1, M2, M3);
111 [lb, ub] = compute_gamma_bounds(M2a, M3a);
112 GAMMAa = max(lb, min(GAMMA, ub));
114 % priorities are M2 > GAMMA > M3
115 % adjust second moment
117 scv = ((M2-M1sq)/M1sq);
119 % (M2 - M1^2)/M1^2 = 1/2
120 % M2 - M1^2 = 1/2 M1^2
123 scva = ((M2a-M1sq)/M1sq);
128 % get bounds on third moment
130 M3_lb = 3*M1^3*(3*scva-1+sqrt(2)*(1-scva)^(3/2));
133 M3_lb = 3/2*M1^3*(1+scva)^2;
136 % compute M3a and GAMMAa
137 if abs(M3_lb - M3_ub) < tol
139 M3a = (M3_lb + M3_ub)/2;
142 % optimization problem formulation
143 problem.Variables = 1;
144 problem.LB = M3_lb + tol;
146 problem.ObjFunction = @gamma_objective;
147 M3a = PSwarm(problem);
148 % compute adjusted gamma
149 [lb, ub] = compute_gamma_bounds(M2a, M3a);
150 GAMMAa = max(lb, min(GAMMA, ub));
153 error(
'Invalid method for adjusting AMAP(2) characteristics');
156 function obj = gamma_objective(M3a)
157 [lb,ub] = compute_gamma_bounds(M2a, M3a);
158 GAMMAa = max(lb, min(GAMMA, ub));
159 obj = weights(2) * (M3a/M3-1)^2 + weights(3) * (GAMMAa/GAMMA-1)^2;
162 function [lb, ub] = compute_gamma_bounds(M2a, M3a)
166 lb = -(N2a*(N3a-6)+6)/(3*N2a-6);
167 ub = -(2* (0.5*(N2a-2)+0.5*sqrt(N2a^2 - 2*N2a*N3a/3))^2 )/(N2a-2);
169 elseif N3a < 9 - 12/N2a
170 lb = -(N2a*(N3a-6)+6)/(3*N2a-6);
173 x1 = sqrt(N2a*(N2a*(18*N2a+N3a*(N3a-18)-27)+24*N3a));
175 lb = (x2-x1+12)/(x2+x1+12);
180 function obj = fun(x)
181 v = (x - [M2 M3 GAMMA]) ./ [M2 M3 GAMMA] .* weights;
185 function obj = fun2(x)
186 v = (x - [M3 GAMMA]) ./ [M3 GAMMA] .* weights(2:3);
190 function [c, ceq] = nonlcon_safe(x)
194 AMAPS = amap2_fit_decay(M1,xM2,xM3,xGAMMA);
203 function [c, ceq] = nonlcon_safe2(x)
206 AMAPS = amap2_fit_decay(M1,M2,xM3,xGAMMA);
215 function [c, ceq] = nonlcon_theoretical(x)
220 % compute normalized moments
224 %m3a_printf(
'M1 = %f, M2 = %f, M3 = %f, GAMMA = %f\n', M1, xM2, xM3, xGAMMA);
225 %m3a_printf(
'n2 = %f, n3 = %f\n', n2, n3);
227 % simplifying notations
for moments bounds. The formulas are only
228 % defined on 3/2 <= n2 < 2, so evaluate them at a CLAMPED n2: an
229 % iterate below 3/2 (which constraint 1
is there to push back) or at
230 % exactly 2 would otherwise leave the third-moment rows at zero, and
231 % M3 would be unconstrained
while constraint 1
is satisfied to solver
232 % tolerance. Observed: the search returning n2 = 3/2 - 1.3e-11 with
233 % n3 = 0.795, where the only admissible n3
is 2.
234 n2b = min(max(n2, 3/2), 2 - 1e-12);
235 p2 = 3*(n2b-2)/(3*n2b) * (-2*sqrt(3)/sqrt(12-6*n2b) - 1);
236 a2 = (n2b-2)/(p2*(1-n2b) + sqrt(p2^2 + (2*p2*(n2b-2))));
237 l2 = 3*(a2+1)/(a2*p2+1) - (6*a2)/(2+a2*p2*(2*a2+2));
240 %
if (M2-M1^2)/M1^2 == 1
241 % m3a_printf(
'Exponential\n');
247 % CONSTRAINT 1: 3/2 <= n
250 % CONSTRAINT 2: l2 <= n3
251 % CONSTRAINT 3: n3 <= u2
255 % CONSTRAINT 2: 3/2 n2 < n3
256 % CONSTRAINT 3: disabled
257 c(2) = 3/2 * n2 - n3 + eps;
261 % BOUNDS FOR AUTOCORRELATION DECAY
262 lb1 = -(n2*(n3-6)+6)/(3*n2-6);
263 ub1 = -(2*(1/2*(n2-2)+1/2*sqrt(n2^2-(2*n2*n3)/3))^2)/(n2-2);
265 tmp2 = sqrt(n2*(n2*(18*n2+n3*(n3-18)-27)+24*n3));
266 lb2 = (tmp1-tmp2+12)/(tmp1+tmp2+12);
267 %m3a_printf(
'LB1 = %f, LB2 = %f\n', lb1, lb2);
269 %m3a_printf(
'LB1 <= gamma: %d\n', lb1 <= xGAMMA);
270 %m3a_printf(
'gamma <= UB: %d\n', xGAMMA <= ub1);
273 elseif n2 > 2 && n3 < 9 - 12/n2
274 %m3a_printf(
'LB1 <= gamma: %d\n', lb1 <= xGAMMA);
275 %m3a_printf(
'gamma <= 1: %d\n', xGAMMA <= 1);
278 elseif n2 > 2 && n3 >= 9 - 12/n2
279 %m3a_printf(
'LB2 <= gamma: %d\n', lb2 <= xGAMMA);
280 %m3a_printf(
'gamma <= 1: %d\n', xGAMMA <= 1);
289 function [c, ceq] = nonlcon_theoretical2(x)
294 % compute normalized moments, from the ADJUSTED second moment that the
295 % bound interval was built on
299 % M3
is always feasible because of the bound constraints
301 % BOUNDS FOR AUTOCORRELATION DECAY
302 lb1 = -(n2*(n3-6)+6)/(3*n2-6);
303 ub1 = -(2*(1/2*(n2-2)+1/2*sqrt(n2^2-(2*n2*n3)/3))^2)/(n2-2);
305 tmp2 = sqrt(n2*(n2*(18*n2+n3*(n3-18)-27)+24*n3));
306 lb2 = (tmp1-tmp2+12)/(tmp1+tmp2+12);
307 %m3a_printf(
'LB1 = %f, LB2 = %f\n', lb1, lb2);
309 %m3a_printf(
'LB1 <= gamma: %d\n', lb1 <= xGAMMA);
310 %m3a_printf(
'gamma <= UB: %d\n', xGAMMA <= ub1);
313 elseif n2 > 2 && n3 < 9 - 12/n2
314 %m3a_printf(
'LB1 <= gamma: %d\n', lb1 <= xGAMMA);
315 %m3a_printf(
'gamma <= 1: %d\n', xGAMMA <= 1);
318 elseif n2 > 2 && n3 >= 9 - 12/n2
319 %m3a_printf(
'LB2 <= gamma: %d\n', lb2 <= xGAMMA);
320 %m3a_printf(
'gamma <= 1: %d\n', xGAMMA <= 1);