Restricting solutions using lsqnonlin with complex unknowns

So, I'm trying to solve a system of equations that has complex numbers, the thing is that it is supossed to be a 12x12, however I write it as a 9 unknowns with 12 equations ever since three of my unknowns
l1,L2,L3
Are complex numbers, where the real and imaginary part are two sepparate unknowns, i'm trying to solve my system with the following code:
fun = @(x)[x(1)*(exp(1i*alfa(1))-1)+x(2)*(exp(1i*x(4))-1)-x(3)*(exp(1i*rho(1))-1),x(1)*(exp(1i*alfa(2))-1)+x(2)*(exp(1i*x(5))-1)-x(3)*(exp(1i*rho(2))-1),x(1)*(exp(1i*alfa(3))-1)+x(2)*(exp(1i*x(6))-1)-x(3)*(exp(1i*rho(3))-1),x(1)*(exp(1i*alfa(4))-1)+x(2)*(exp(1i*x(7))-1)-x(3)*(exp(1i*rho(4))-1),x(1)*(exp(1i*alfa(5))-1)+x(2)*(exp(1i*x(8))-1)-x(3)*(exp(1i*rho(5))-1),x(1)*(exp(1i*alfa(6))-1)+x(2)*(exp(1i*x(9))-1)-x(3)*(exp(1i*rho(6))-1)];
[x,fval] = lsqnonlin(fun,[40+20i,40+20i,40+40i,1,1,1,1,1,1])
L1=x(1)
l2=x(2)
L3=x(3)
phi1=x(4)
phi2=x(5)
phi3=x(6)
phi4=x(7)
phi5=x(8)
phi6=x(9)
I need to restrict the solutions to only those who have phi1, phi2, phi3, phi4, phi5, phi6 stricly as real numbers, without any complex part
Full code below
%Introducción de puntos y cambio de eje de referencia
%Los puntos se escogieron de acuerdo al trabajo del mecanismo de 10 barras
clc
clear all
L=82.4;
L2=42.7;
l1=39.7;
Px=[6.56044 -4.12471 -19.6017 -18.2934 -1.8923 21.1196 17.6706];
Py=[0.995643 0.00147957 1.14159 2.07962 6.30745 11.3302 4.55826];
Theta1=[1.8073522328820310935623781790315, 1.6640119075452171534709629667332, 1.6070200513956322755772098198635, 1.6722276935006778576202574721229, 2.0499843737905114408996166747857, 2.5269236792605256431572972964069, 2.104035221140493127739748316949];
Theta2=[1.5061633838536617569715490239474, 1.3818662717816540137480189935275, 1.0670342257290320137842410556993, 1.039607130354159250776488333576, 1.0892436455770986051727755147433, 1.206386181298577448316370700124, 1.5032866660028009663082593137064];
Theta1_Grados=round(Theta1,3)*(180/pi)
Theta2_Grados=round(Theta2,3)*(180/pi)
for j=1:6
alfa(j)=(Theta1(j+1)-Theta1(j)); %Alfa representa el cambio de una posición en grados a otra
end
AlfaGrados=alfa*(180/pi)
%Angulos de entrada de la manivela para generar una unica rotacion de 360
%grados, que se distribuye de forma uniforme para la generación de función
gamma=[40 70 100 180 240 360 40];
for j=1:6
rho(j)=(gamma(j+1)-gamma(j))*(pi/180);
end
%Sistemas de ecuaciones
fun = @(x)[x(1)*(exp(1i*alfa(1))-1)+x(2)*(exp(1i*x(4))-1)-x(3)*(exp(1i*rho(1))-1),x(1)*(exp(1i*alfa(2))-1)+x(2)*(exp(1i*x(5))-1)-x(3)*(exp(1i*rho(2))-1),x(1)*(exp(1i*alfa(3))-1)+x(2)*(exp(1i*x(6))-1)-x(3)*(exp(1i*rho(3))-1),x(1)*(exp(1i*alfa(4))-1)+x(2)*(exp(1i*x(7))-1)-x(3)*(exp(1i*rho(4))-1),x(1)*(exp(1i*alfa(5))-1)+x(2)*(exp(1i*x(8))-1)-x(3)*(exp(1i*rho(5))-1),x(1)*(exp(1i*alfa(6))-1)+x(2)*(exp(1i*x(9))-1)-x(3)*(exp(1i*rho(6))-1)];
[x,fval] = lsqnonlin(fun,[40+20i,40+20i,40+40i,1,1,1,1,1,1])
L1=x(1)
l2=x(2)
L3=x(3)
phi1=x(4)
phi2=x(5)
phi3=x(6)
phi4=x(7)
phi5=x(8)
phi6=x(9)

 Accepted Answer

l1,L2,L3 are complex numbers, where the real and imaginary part are two sepparate unknowns,
If so, then you have 12 unknowns, not 9. Write your function in terms of 12 unknowns so that lsqnonlin knows that:
fun = @(P) residualFunction(P,rho,alfa);
[P,fval] = lsqnonlin(fun,[40,20,40,20,40,40,1,1,1,1,1,1]);
L=complex(P(1:3), P(4:6));
phi=P(7:end);
function F=residualFunction(P,rho,alfa)
x(1:3)=complex(P(1:2:6), P(2:2:6));
x(4:9)=P(7:end);
expr= [x(1)*(exp(1i*alfa(1))-1)+x(2)*(exp(1i*x(4))-1)-x(3)*(exp(1i*rho(1))-1),x(1)*(exp(1i*alfa(2))-1)+x(2)*(exp(1i*x(5))-1)-x(3)*(exp(1i*rho(2))-1),x(1)*(exp(1i*alfa(3))-1)+x(2)*(exp(1i*x(6))-1)-x(3)*(exp(1i*rho(3))-1),x(1)*(exp(1i*alfa(4))-1)+x(2)*(exp(1i*x(7))-1)-x(3)*(exp(1i*rho(4))-1),x(1)*(exp(1i*alfa(5))-1)+x(2)*(exp(1i*x(8))-1)-x(3)*(exp(1i*rho(5))-1),x(1)*(exp(1i*alfa(6))-1)+x(2)*(exp(1i*x(9))-1)-x(3)*(exp(1i*rho(6))-1)];
F=[ real(expr(:)),imag(expr(:)) ];
end

11 Comments

x(4:9)=P(7:end);
instead of
x(4:12)=P(7:end);
The result is not that exciting:
x(1) = x(2) = x(3) = 0, x(4),x(5),x(6),x(7),x(8),x(9) arbitrary.
Thanks for the help.
I think I will try to add a genetic algorithm that looks to minimize the imaginary part of the alfa
You're welcome, but if your question has been answered, please Accept-click.
I think I will try to add a genetic algorithm that looks to minimize the imaginary part of the alfa
The alfa are real - so the imaginary part is minimal already.
And as said - as long as your expressions are multiplied by x(1), x(2) and x(3) which can be chosen equal to 0, the alfa's and rho's can be arbitrary. The equations will always be =0 automatically.
Can't I add a constrain related to the value of x(1), x(2) and x(3)?, at least my physical problem I know that it can't be something lower than 5, for example
I thought x(1),x(2) and x(3) are complex.
So what can't be lower than 5 then ? The absolute value ? The real part ? The imaginary part ?
You can specify constraints on the parameters in lb and ub in the call to lsqnonlin at the appropriate positions.
None of the parts can be lower than 5, in this case.
I tried to do that, but ever since there are complex numbers it wont allow me
There are no complex numbers in the formulation I have given you.
Matt's solution does not work with complex numbers directly, but with their real and imaginary parts which are "glued together" in "residualFunction" by the command
x(1:3)=complex(P(1:2:6), P(2:2:6));
So you can set constraints on the real and imaginary parts of x(1),x(2) and x(3).
To set a constraint on the absolute value of x(1),x(2) and/or x(3), you will have to use "fmincon" instead of "lsqnonlin", I guess.
Thanks, tried to adjust the constraints to what makes sense in my problem, I'm going to check if it works or not.

Sign in to comment.

More Answers (0)

Categories

Find more on Mathematics in Help Center and File Exchange

Products

Release

R2022a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!