Particle swarm optimization solving an equation system
5 次查看(过去 30 天)
显示 更早的评论
I want to use particle swarm optimization to solve 4 complex valued nonlinear equations just to compare the results I got from other optimizers. It is working but I'm getting a single value for each variable not in the form of "a+bi" or "a-bi" because of the norm I guess. When I remove the "norm" I am getting an error message. How can I fix the poroblem? Thanks for the help.
ObjFnc = @(x) [...]; % Equations
nVars = 4;
LB = [-1,-1,-1,-1];
UB = [1,1,1,1];
PS_Opts = optimoptions('particleswarm','HybridFcn',@fmincon);
[x,fval,exitflag,output] = particleswarm(@(x)norm(ObjFnc(x)),nVars,LB,UB,PS_Opts)
0 个评论
采纳的回答
Dana
2020-8-18
As far as I know, you cannot directly optimize using complex variables as your optimizing variables, and of course your objective function must be a real scalar so you can't have a comlex variable there either.
All is not lost, however. Instead of having 4 complex variables x1, x2, x3, x4 as your optimizers, have 8 real variables a1, b1, a2, b2, a3, b3, a4, b4, and then in your objective function convert these to complex variables via x1=a1+b1*i, x2=a2+b2*i, etc.
9 个评论
Dana
2020-8-18
First of all I think you'll find this easier to program if you make ObjFnc a proper function (i.e., in its own .m file), rather than an anonymous one as you have. Then that .m file could look something like:
function obj = ObjFnc(ab)
% The input ab here would be a vector of length 8, with the first 4 elements
% being the real parts of the x's, and the last 4 the complex parts.
Sd1 = -0.063933409 - 0.18155469 * 1i;
...
Sd4 = -0.981188030 + 0.15023738 * 1i
x = ab(1:4) + ab(5:8)*1i;
obj = x(1)-Sd1-x(2).*((x(4).*(x(3)-x(2)+...;
-Sd2-x(4).*((x(2).*(x(3).*x(2)+x(3).*...;
x(1)-Sd3+x(2).*((x(2).*(x(4).^2.*x(2).*x(3).^2...;
-Sd4-x(4).*((x(4).*(x(2).*x(1)-1).^2)./(x(3).^2...];
end
You can then optimize this with the particle swarm as
nVars = 8;
[abopt,fval,exitflag,output] = particleswarm(@(ab)norm(ObjFnc(ab)),nVars,LB,UB,PS_Opts);
The only remaining issue you'd need to address here is the constraints on the elements of ab. You originally had
LB = [-1,-1,-1,-1];
UB = [1,1,1,1];
but (a) that wouldn't make sense even if ObjFnc took complex inputs (is 0.9+0.2i < or > than 1?), and (b) you now need to put bounds on both the real and imaginary parts, so these vectors would need to each have 8 elements in them. If you don't actually have constraints, you can just omit these arguments altogether. If you do have constraints, you need to think carefully about how to deal with them, and depending on the form they take this may require a change of variables.
For example, if you want to constrain |xj| <= 1, then you're going to have to take a different approach, since this is a joint restriction on aj and bj, and you can't do that with particleswarm. In that case, rather than using the real and imaginary parts of the x's as the function inputs, you might be better off working in polar coordinates:
function obj = ObjFnc(thR)
% The input thR here would be a vector of length 8, with th = thR(1:4), R = thR(5:8),
% and x(j) = R*exp(th*i) = R*(cos(th) + i*sin(th)).
Sd1 = -0.063933409 - 0.18155469 * 1i;
...
Sd4 = -0.981188030 + 0.15023738 * 1i
th = thR(1:4);
R = thR(5:8);
x = R*exp(th*1i);
obj = x(1)-Sd1-x(2).*((x(4).*(x(3)-x(2)+...;
-Sd2-x(4).*((x(2).*(x(3).*x(2)+x(3).*...;
x(1)-Sd3+x(2).*((x(2).*(x(4).^2.*x(2).*x(3).^2...;
-Sd4-x(4).*((x(4).*(x(2).*x(1)-1).^2)./(x(3).^2...];
end
In this case, you can bound the elements of R between -1 and 1, which will ensure that |x|<=1. Technically you could also bound the angle th between, say, and π, but this may create numerical issues near the boundaries. It might be better to just leave the angle unbounded (i.e., use bounds -Inf, Inf).
更多回答(1 个)
Ceyhan TURKMEN
2020-12-3
Are the first 4 values real and the last 4 values imaginary part of the results?
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Direct Search 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!