Symbolic comprision operation and summation cant get right answer - matlab

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.

Related

large number of linear equations in MATLAB

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.

how can I verify that a set of 4 points have undergone an affine transformation

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.

Does Maxima have a function for solving systems of linear inequalities, that would also be available on Moodle Stack-exams?

What's in the title. I've tried the following:
/*Constants*/
metalMaxTa : 37;/*rand_with_step(20,40,2);*/
elecMaxTa : 52;/*rand_with_step(40,60,2);*/
rateAa : 24;
rateBa : 44;
/*Conditions set by the problem*/
ineq1 : 1/2 * x1 + x2 <= metalMaxTa;
ineq2 : x1 + 1/2*x2 <= elecMaxTa;
ineq3 : x1 >= 0;
ineq4 : x2 >= 0;
/*Solution?*/
sol : solve_rat_ineq([ineq1,ineq2,ineq3,ineq4],[x1,x2]);
but all that returns is this:
In other words, nothing is really done to the input system, the expression is simply printed. The load-command is not available, so I can't actually load the function if it's not available, which seems to be the problem.
EDIT: to_poly_solve() also produces the same output. solve() seems to be available, but returns an empty list, as it is apparently meant for systems of equations, not inequalities.
fourier_elim can handle it.
load('fourier_elim)$
metalMaxTa : 37 $
elecMaxTa : 52 $
rateAa : 24 $
rateBa : 44 $
ineq1 : 1/2 * x1 + x2 <= metalMaxTa$
ineq2 : x1 + 1/2*x2 <= elecMaxTa $
ineq3 : x1 >= 0 $
ineq4 : x2 >= 0 $
sol : fourier_elim([ineq1,ineq2,ineq3,ineq4], [x1, x2]) $
map(disp, sol) $
returns
[x1 = 0, x2 = 0]
[x1 = 52, x2 = 0]
[x2 = 0, 0 < x1, x1 < 52]
[x1 = 0, x2 = 37]
[x1 = 0, 0 < x2, x2 < 37]
134 44
[x1 = ---, x2 = --]
3 3
x2 - 104 44
[x1 = - --------, 0 < x2, x2 < --]
2 3
44
[x1 = 74 - 2 x2, -- < x2, x2 < 37]
3
x2
[0 < x1, x1 < min(52 - --, 74 - 2 x2), 0 < x2, x2 < 37]
2
It uses only strict inequalities in the output and shows equities as
special cases. If you use strict inequalities in equations the output
looks more natural.
0 < x1
x2
x1 < min(52 - --, 74 - 2 x2)
2
0 < x2
x2 < 37

Solving a linear system of equation with two variables in MATLAB

It might seem a simple question. I need it, though. Let's assume we have two equations:
2 * y + x + 1 = 0
and
y - 2 * x = 0
I would like to find their bisection which can be calculated from this equation:
|x + 2 * y + 1| |-2 *x + y |
------------------- = -----------------
(sqrt(2^2 + 1^2)) (sqrt(1^2 + 2^2))
To make the long story short, we only need to solve this below system of equation:
2 * y + x + 1 = -2 *x + y
and
2 * y + x + 1 = 2 *x - y
However, using solve function of MATLAB:
syms x y
eqn1 = 2 * y + x + 1 == -2 *x + y ;
eqn2 = 2 * y + x + 1 == 2 *x - y ;
[x, y] = solve (eqn1 , eqn2, x, y) ;
Will give me:
x = -1/5 and y = -2/5
But, I am looking for the result equations, which is:
y = -3 * x - 1 and 3 * y = 2 * x - 1
So, does anyone know how I can get the above line equation instead of the result point? Thanks,
The following should solve both equations with y on the left-hand-side:
y1 = solve(eqn1,y)
y2 = solve(eqn2,y)
Result:
y1 =
- 3*x - 1
y2 =
x/3 - 1/3
As an aside, it would be much faster to solve this system by thinking of it it as a matrix inversion problem Ax=b rather than using MATLAB's symbolic tools:
A = [1 2; -2 1];
b = [-1; 0];
x = A\b
Result:
x =
-0.2000
-0.4000

Solve for influence of nodes in graph in Matlab

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]