I am writing an algorithm for my project , and at some point I need to find the value of alpha that will minimize a function subject to constraints.
Error : Using horzcat Nonscalar arrays of function handles are not
allowed; use cell arrays instead.
This is what I have
syms x1 x2 x3 x4;
syms alpha;
f=(exp(x1))*(4*(x1).^2 + 2*(x2).^2 + 4*(x1)*(x2) + 2*(x2) + 1) + 0*x3 + 0*x4;
%constraints must be equal to 0
g1=x1*x2-x1-x2+x3+1.5;
g2=x1*x2-x4+10;
%Give initial values, given that x1 is between -10 and -9 and x2 is between
%1 and 1.5, and the slacks x3 and x4 are strictly between 0 and 1.
lb=[-10 1 0 0];
ub=[-9 1.5 1 1];
xo=[-9 1 0.1 0.1];
if (-10<=xo(1)) && (xo(1)<=-9) && (1<=xo(2)) && (xo(2)<=1.5)
xi(1)=xo(1);
xi(2)=xo(2);
xd(1)=xo(3);
xd(2)=xo(4);
end
%Evaluation of Gradient of f
gradfi(1,1)=subs(diff(f,x1),{x1 x2 x3 x4},{xi(1) xi(2) xd(1) xd(2)});
gradfi(2,1)=subs(diff(f,x2),{x1 x2 x3 x4},{xi(1) xi(2) xd(1) xd(2)});
gradfd(1,1)=subs(diff(f,x3),{x1 x2 x3 x4},{xi(1) xi(2) xd(1) xd(2)});
gradfd(2,1)=subs(diff(f,x4),{x1 x2 x3 x4},{xi(1) xi(2) xd(1) xd(2)});
%Evaluation of Jacobian Matrix
Ji1=subs(jacobian(g1,[x1 x2]),{x1 x2 x3 x4},{xi(1) xi(2) xd(1) xd(2)});
Ji2=subs(jacobian(g2,[x1 x2]),{x1 x2 x3 x4},{xi(1) xi(2) xd(1) xd(2)});
Ji=[Ji1;Ji2];
Jd1=subs(jacobian(g1,[x3 x4]),{x1 x2 x3 x4},{xi(1) xi(2) xd(1) xd(2)});
Jd2=subs(jacobian(g2,[x3 x4]),{x1 x2 x3 x4},{xi(1) xi(2) xd(1) xd(2)});
Jd=[Jd1;Jd2];
gammai=-(gradfi - ((gradfd.')*Jd^(-1)*Ji).');
deltad=-Jd^(-1)*Ji*(gammai);
x1=xi(1)+gammai(1)*alpha;
x2=xi(2)+gammai(2)*alpha;
x3=xd(1)+deltad(1)*alpha;
x4=xd(2)+deltad(1)*alpha;
falpha =matlabFunction((exp(x1))*(4*(x1).^2 + 2*(x2).^2 + 4*(x1)*(x2) + 2*(x2) + 1) + 0*x3 + 0*x4);
c=([-10-x1; x1+9; -x2+1;x2-1.5;-x3;x3-1;-x4;x4-1]);
ceq=([x1*x2-x1-x2+x3+1.5;x1*x2-x4+10]);
const=([matlabFunction(c), ceq]);
[alpha]=fmincon(falpha,0,[],[],[],[],[],[],const);
Related
I want to use solve() to solve a large system of linear equations. The solve() function needs equations and variables. I use a loop to generate the equations and my variables are contained in a large array. This is a simple code of what I am trying to do:
x = sym('x',[1 3])
eqn = sym('eqn', [1,3])
eqn1 = 2*x1 + x2 + x3 - 2 == 0
eqn2 = 2*x2 -x2 -x1- x3 == 3
eqn3 = 2*x2+ x1 + 3*x3 == -10
Y = solve(eqn, x)
MATLAB does not recognize my variable x1. I have solved the same system using the following code:
syms x1 x2 x3
eqn1 = 2*x1 + x2 + x3 == 2
eqn2 = 2*x2 -x2 -x1 - x3 == 3
eqn3 = 2*x2+ x1 + 3*x3 == -10
X = solve([eqn1, eqn2, eqn3, eqn4], [x1 x2 x3])
structfun(#subs,X)
But this is useless for a very large number of equations. What am I doing wrong?
You don't need symbolic (syms) for that. This is a standard linear system of equations that can be represented as:
Ax = b where A = [2 1 1; -1 1 -1; 1 2 3], x = [x1; x2; x3] and b = [0; 3; -10]
To solve for x, you would first define
A = [2 1 1; -1 1 -1; 1 2 3]
and
b = [0; 3; -10]
and then solve using
x = A\b
PS. There are some odd things in your question, eg. in eq.2 eqn2 = 2*x2 -x2 -x1- x3 == 3 I assume you omitted simplying this to -x1 +x2 -x3 ==3.
PS2. This is pretty standard Matlab, you can find a lot of info under the standard mldivide page in the documentation along with a lot similar questions here on SO.
I'm confused about MATLAB's symbolic operation precedence. My code does not produce the desired output.
syms x1 x2 x3 x4
aa=((x1 == 0 & x2 == 0 & x3 == 0 & x4 == 0) + ((9*x1)/50 + (327*x2)/2000 + (1841*x3)/20000 + (1799*x4)/20000));
bb=eval(subs(aa, [x1 x2 x3 x4], [0.2 0.2 0.2 0.2]))
I expect the output of
bb=
0.1051
but the actual output is
bb =
logical
0
Why does MATLAB do this?
I use MATLAB R2018b
Case 1: x == y
syms x y z
aa = (x == y) + z
Meaning
aa = [x or y] + z = x + z = y + z
Wherever you have x, you can replace it by y, interchangeably.
It does not check if x and y are the same
Case 2: isequal(x, y)
syms x y z
aa = (x == y) + z
aa = isequal(x, y) + z
Meaning
aa = [check if x and y are the same] + z = 0 + z = z
Modify the given code to this using isequal()
syms x1 x2 x3 x4
aa=((isequal(x1, 0)& isequal(x2, 0) & isequal(x3, 0) & isequal(x4, 0)) + ...
((9*x1)/50 + (327*x2)/2000 + (1841*x3)/20000 + (1799*x4)/20000));
bb=eval(subs(aa, [x1 x2 x3 x4], [0.2 0.2 0.2 0.2]));
Result
bb = 0.1051
I think MATLAB tries to reduce the number of brackets necessary to produce the simplest output. Note that if a is equal to b, a+c is also equal to b+c, so the statement is not wrong. If you call simplify(aa) you even get a simple a == b, which is indeed the simplest form as one can cancel the c on both sides:
syms a b c
aa=(a==b)+c
aa =
a + c == b + c
pretty(aa)
a + c == b + c
simplify(aa)
ans =
a == b
With respect to your edited question: why are you using symbolic variables at all? They are slow and cumbersome (not to speak about the unspeakable evil that is eval). Using numeric computation does yield the correct result:
syms x1 x2 x3 x4
aa=((x1 == 0 & x2 == 0 & x3 == 0 & x4 == 0) + ((9*x1)/50 + (327*x2)/2000 + (1841*x3)/20000 + (1799*x4)/20000));
bb=eval(subs(aa, [x1 x2 x3 x4], [0.2 0.2 0.2 0.2]))
bb =
logical
0
x1=0.2;x2=0.2;x3=0.2;x4=0.2;
(x1 == 0 & x2 == 0 & x3 == 0 & x4 == 0)
ans =
logical
0
((9*x1)/50 + (327*x2)/2000 + (1841*x3)/20000 + (1799*x4)/20000)
ans =
0.1051
aa=((x1 == 0 & x2 == 0 & x3 == 0 & x4 == 0) + ((9*x1)/50 + (327*x2)/2000 + (1841*x3)/20000 + (1799*x4)/20000))
aa =
0.1051
I suspect the problem is somewhere in the belly of subs and/or eval.
I have two images containing same object with 4 corners.
I have a correspondence for those 4 points between images.
Let us call these points as A,B,C,D .
I have (x,y) coordinates of A in image 1 and image 2 .
Similiarly , for points B,C,D .
My aim is to verify that if there exists an affine transformation that satisfies this coordinate change of these 4 points.
How should I proceed ?
It would be beneficial if there is a code in python or c so that I can quickly verify for many images.
My understanding is that a general affine transformation can be described by
x'=ax+by+c
y'=dx+ey+f
So there are six unknowns.
Thanks for reading.
Let's say your points are A=(x1,y1); B=(x2,y2); C=(x3;y3); D=(x4,y4) in image 1 and A'=(x1',y1'); B'=(x2',y2'); C'=(x3';y3'); D'=(x4',y4') in image 2.
You already figured out that finding the affine transformation requires you to find the six unknowns. To find them, just write down the system of linear equations and solve:
x1' = a x1 + b y1 + c
y1' = d x1 + e y1 + f
x2' = a x2 + b y2 + c
y2' = d x2 + e y2 + f
x3' = a x3 + b y3 + c
y3' = d x3 + e y3 + f
x4' = a x4 + b y4 + c
y4' = d x4 + e y4 + f
You can actually split this into two systems of linear equations:
x1' = a x1 + b y1 + c
x2' = a x2 + b y2 + c
x3' = a x3 + b y3 + c
x4' = a x4 + b y4 + c
and
y1' = d x1 + e y1 + f
y2' = d x2 + e y2 + f
y3' = d x3 + e y3 + f
y4' = d x4 + e y4 + f
Since you are only interested in whether there exists an affine transformation (but not in the values of a, b, c, d, e, f itself), you just have to determine if these two systems of linear equations have a solution or not.
The Rouché–Capelli theorem tells us that a system of linear equations has a solution if and only if the rank of the coefficient matrix equals the rank of the augmented matrix.
In your case, the coefficient matrix for both systems of linear equations is
| x1 y1 1 |
| x2 y2 1 |
| x3 y3 1 |
| x4 y4 1 |
The augmented matrix for the first system of linear equations is
| x1 y1 1 x1' |
| x2 y2 1 x2' |
| x3 y3 1 x3' |
| x4 y4 1 x4' |
and for the second system of linear equations it is
| x1 y1 1 y1' |
| x2 y2 1 y2' |
| x3 y3 1 y3' |
| x4 y4 1 y4' |
Now compute the ranks of these three matrices (for example with numpy.linalg.matrix_rank) and if they are all equal, there exists an affine transformation.
I have a directed, unweighted graph with 5 nodes: x1 through x5. The edges are:
x1->x3
x2->x1
x2->x5
x3->x2
x3->x4
x4->x5
x5->x2
I want to solve this set of equations corresponding to the graph:
x1 = alpha * x2
x2 = alpha * (x3 + x5)
x3 = alpha * x1
x4 = alpha * x3
x5 = alpha * (x2 + x4)
x1 + x2 + x3 + x4 + x5 = 1
How can I set up these equations and solve in Matlab? I want the values of x1 through x5 for which the equations hold.
Here is the solution that worked for me:
syms a b c d e alpha
S = solve(-a+alpha*b==0, -b+alpha*c+alpha*d==0, alpha*a-c==0, alpha*c-d==0, ...
alpha*d-e==0, a+b+c+d+e==1);
S = [S.a S.b S.c S.d S.e S.alpha]
I want to transform a quadrilateral image to a rectangular image which I know those vertices. for example in the image below, I know the coordinate (X1,Y1) ~ (X4,Y4) and (x1,y1) ~ (x2,y2) and I want to transform it into rectangle. how can I obtain (x,y) coordinate in rectangular image which is correspond to (X,Y) coordinate in quadrilateral image?
____> Y ____> y
| |
| |
V V
X x
(X1,Y1) (X2,Y2) (x1,y1) (x1,y2)
________ _________
/ .(X,Y) \ => | .(x,y) |
/__________\ |_________|
(X3,Y3) (X4,Y4) (x2,y1) (x2,y2)
If this is supposed to be a perspective transformation, the term you look for is homography.
Maybe the Matlab functions in these links cando what you want:
http://www.csse.uwa.edu.au/~pk/research/matlabfns/#projective
http://www.robots.ox.ac.uk/~vgg/hzbook/code/
Edited after comments:
Ok, so I solved the equations with Mathematica. If you define (for readability)
M=(x-x1)/(x2-x1)
and
N=(y-y1)/(y2-y1),
then the pair of solutions is the rather unwieldy
{M -> -(X1 Y - X3 Y + X4 Y - X Y1 - X4 Y1 + X Y2 - 2 X1 Y2 + X3 Y2 +
X Y3 - X2 (Y - 2 Y1 + Y3) - X Y4 +
X1 Y4 + \[Sqrt](4 (X3 (-Y + Y1) + X1 (Y - Y3) +
X (-Y1 + Y3)) (-(X3 - X4) (Y1 - Y2) + (X1 - X2) (Y3 -
Y4)) + (X4 (-Y + Y1) + X3 (Y - 2 Y1 + Y2) +
X2 (Y - Y3) - X1 (Y - 2 Y3 + Y4) +
X (Y1 - Y2 - Y3 + Y4))^2))/(2 (-(X2 - X4) (Y1 -
Y3) + (X1 - X3) (Y2 - Y4))),
N -> -(-X2 Y - X3 Y + X4 Y - X Y1 + 2 X3 Y1 - X4 Y1 + X Y2 - X3 Y2 +
X Y3 + X2 Y3 - X Y4 +
X1 (Y - 2 Y3 +
Y4) - \[Sqrt](4 (X3 (-Y + Y1) + X1 (Y - Y3) +
X (-Y1 + Y3)) (-(X3 - X4) (Y1 - Y2) + (X1 - X2) (Y3 -
Y4)) + (X4 (-Y + Y1) + X3 (Y - 2 Y1 + Y2) +
X2 (Y - Y3) - X1 (Y - 2 Y3 + Y4) +
X (Y1 - Y2 - Y3 + Y4))^2))/(2 (-(X3 - X4) (Y1 -
Y2) + (X1 - X2) (Y3 - Y4)))}
and
{M -> -(X1 Y - X3 Y + X4 Y - X Y1 - X4 Y1 + X Y2 - 2 X1 Y2 + X3 Y2 +
X Y3 - X2 (Y - 2 Y1 + Y3) - X Y4 +
X1 Y4 - \[Sqrt](4 (X3 (-Y + Y1) + X1 (Y - Y3) +
X (-Y1 + Y3)) (-(X3 - X4) (Y1 - Y2) + (X1 - X2) (Y3 -
Y4)) + (X4 (-Y + Y1) + X3 (Y - 2 Y1 + Y2) +
X2 (Y - Y3) - X1 (Y - 2 Y3 + Y4) +
X (Y1 - Y2 - Y3 + Y4))^2))/(2 (-(X2 - X4) (Y1 -
Y3) + (X1 - X3) (Y2 - Y4))),
N -> -(-X2 Y - X3 Y + X4 Y - X Y1 + 2 X3 Y1 - X4 Y1 + X Y2 - X3 Y2 +
X Y3 + X2 Y3 - X Y4 +
X1 (Y - 2 Y3 +
Y4) + \[Sqrt](4 (X3 (-Y + Y1) + X1 (Y - Y3) +
X (-Y1 + Y3)) (-(X3 - X4) (Y1 - Y2) + (X1 - X2) (Y3 -
Y4)) + (X4 (-Y + Y1) + X3 (Y - 2 Y1 + Y2) +
X2 (Y - Y3) - X1 (Y - 2 Y3 + Y4) +
X (Y1 - Y2 - Y3 + Y4))^2))/(2 (-(X3 - X4) (Y1 -
Y2) + (X1 - X2) (Y3 - Y4)))}
Note that the only difference is the sign before the Srqt.
Now you only have to re-form the definitions of M and N above to get x,y. x=M*(x2-x1)+x1, y=N*(y2-y1)+y1.