Let's say I have 2 symbolic equations in 3 variables:
syms u v w
eq1 = u+v+w == 0
eq2 = w == 0
which both should equal 0.
Is there a way to feed these equations to Matlab and have Matlab conclude:
u=-v
w=0
I tried the following:
%Attempt 1:
x=solve([eq1 eq2],[u v w]);
x.u, x.v, x.w
%Outputs 0 for each of these
% Attempt 2:
[A,B]=equationsToMatrix([eq1 eq2],[u v w]);
linsolve(A,B)
%Outputs 0 for all variables and gives a warning "Warning: The system is rank-deficient. Solution is not unique."
So it only seems to return the trivial zero-solution. This is of course an elementary example. I want it to work for 81 intertwined variables.
Since you have two equations you can only solve for two variables, not for three. You want to see u=-v and w=0, that is a solution in u and w but not in v.
For me x = solve([eq1,eq],u,w) works, it gives x.u=-v and x.w=0.
Related
I've been set a question asking me to solve a system of linear equations. In the question it states I should set up a matrix A and column vector b to solve the equation Ax=b, where x is the column vector (w x y z).
A = [1 1 1 1; 0 1 4 -2; 2 0 -2 1; 1 -2 -1 1]
b = [28;7;22;-4]
A1 = inv(A).*b
sum(A1,2)
This is what I've done so far, however I know the answer that MATLAB gives me is incorrect, as the right solutions should be w=10.5, x=9, y=2.5, z=6.
Can someone point me in the right direction/ show me where I'm going wrong? (I'm fairly new to MATLAB so very unsure about it all).
Thanks.
A = [1 1 1 1; 0 1 4 -2; 2 0 -2 1; 1 -2 -1 1];
b = [28;7;22;-4];
A1 = A \ b;
ans = sum(A1,2);
For a reference concerning the \ operator, please read this: https://it.mathworks.com/help/matlab/ref/mldivide.html
The correct code to use your technique would be:
A1 = inv(A) * b;
but as you may notice, the Matlab code analyzer will point out that:
For solving a system of linear equations, the inverse of a
matrix is primarily of theoretical value. Never use the inverse of a
matrix to solve a linear system Ax=b with x=inv(A)*b, because it is
slow and inaccurate.
Replace inv(A)*b with A\b
Replace b*inv(A) with b/A
and that:
INV(A)*b can be slower than A\b
I have three polynomials a(x), b(x) and p(x) over Galois field GF(2^n), and I would like to compute a(x)*b(x) % p(x). Can Matlab compute this expression? So far, I have found this, but it doesn't consider the p(x):
m=n;
a=[1 0 0 0 1 2] % just a example of numbers, the same type arrays for b and p as well
c = gfconv(a,b,m)
It is what I have found after days of searching, but I cannot find anywhere the formula for the type of equation I have.
I think you're looking for remd in this expression (http://nl.mathworks.com/help/comm/galois-fields-of-odd-characteristic.html).
a = gf([1 0 0 0 1 2],n); %your example
b = gf([1 1],n); %just example
p = gf([1 0],n); % just example
[quot,remd] = deconv(conv(a,b),p);
Note that functions gfconv and gfdeconv exist, but Matlab recommends to use standard conv and deconv over 2^n field.
Thanks much for your time and for all your help.
Actually, I made a mistake in the previous post when specifying the problem. Thus, I reformulate my question using a simpler example. I need to solve symbolically the equation Ct = Z/(P-I) or Ct*(P-I) = Z.
I already know the answer => Ct = [sigma, 1-sigma]
How to program "correctly" the code in order to get the solution
syms sigma;
Ct = sym('Ct',[1 2]);
%
P = [sigma 1-sigma;
sigma 1-sigma];
I = [1 0;
0 1];
Z = [0 0];
%
solve(Ct*(P-I) == Z);
So far, I get :
Z =
0 0
Warning: The solutions are parametrized by the symbols:
z = C_
In solve at 190
In test_matrix_sigma at 13
Or with
solve(Ct == Z/(P-I), Ct);
I get:
Warning: System is rank deficient. Solution is not unique.
Warning: 4 equations in 2 variables.
In /opt/MATLAB/R2013a/toolbox/symbolic/symbolic/symengine.p>symengine at 56
In mupadengine.mupadengine>mupadengine.evalin at 97
In mupadengine.mupadengine>mupadengine.feval at 150
In solve at 170
In test_matrix_sigma at 13
---------------------------------------------------------------------------------------
Thanks for the answer !
Now I have two issues:
1) When I try to handla a more complicated system:
syms a b P1 P2;
I = [1 0 0 0;
0 1 0 0;
0 0 1 0;
0 0 0 1];
%
P = [a*P1 (1-a)*P1 (1-b)*(1-P1) b*(1-P1);
a*P1 (1-a)*P1 (1-b)*(1-P1) b*(1-P1);
b*(1-P2) (1-b)*(1-P2) (1-b)*P2 b*(1-P2);
b*(1-P2) (1-b)*(1-P2) (1-b)*P2 b*(1-P2)];
%
assume(a, 'real');
assume(b, 'real');
assume(P1, 'real');
assume(P2, 'real');
%
answer = null((P-I)');
disp(answer);
I get
ans =
[ empty sym ]
as the only answer.
2) If there is a way in maltlab to "solve" the above symbolic matrix P and find the symbolic determinant ?
For instance, if I do eid(P) it works;
when I do det(P) it gives 0 as answer...
This post is an answer to a different problem, that was first asked by the OP before being edited. I leave the problem and solution here in case someone ever runs into the same problem:
I need to solve symbolically the following matrix equation to find out Ct (a vector ???):
syms a b P1 P2
%
P = [a*P1 (1-a)*P1 (1-b)*(1-P1) b*(1-P1);
a*P1 (1-a)*P1 (1-b)*(1-P1) b*(1-P1);
b*(1-P2) (1-b)*(1-P2) (1-b)*P2 b*(1-P2);
b*(1-P2) (1-b)*(1-P2) (1-b)*P2 b*(1-P2)];
%
solve(Ct*(P-1) == 0, Ct);
How to proceed ?
So far I get:
Undefined function or variable 'Ct'.
Error in matrix_test (line 10) solve(Ct*(P-1) == 0, Ct);
The error you get is because you did not assign Ct before trying to solve for your equation. In the equation Ct*(P-1) == 0, Matlab does not know what Ct is. You could remedy this by creating a symbolic vector (see sym documentation). For instance:
Ct = sym('Ct', [1 4]);
However, using solve on this would not give you the solutions you're looking for: instead, Matlab is going to give you the trivial answer Ct = 0, which of course is a correct answer to your equation.
What you really want to find is the null space of the (P-1)' matrix: the null space is the set of vectors X such that (P-1)'X = 0 (Which is the same thing as X'(P-1) = 0, so Ct = X'). The Matlab function null (see doc) is what you need. Using your code, I get:
null((P-1)')
ans =
[ -1, 0]
[ 1, 0]
[ 0, -1]
[ 0, 1]
This means that any linear combination of the vectors [-1, 1, 0, 0] and [0, 0, -1, 1] belong to the null space of (P-1)', and therefore its transpose is the Ct you were looking for.
N.B.: This result is easily confirmed by observation of your initial matrix P.
This edited problem is only slightly different from the first one. Once again, you are looking to solve an homogeneous system of linear equations.
The warnings you get simply warn you of that: there are an infinity of solutions ; The first warning tells you that the answer is parameterized by C_ (meaning it's in the complex plane, you could add assume(sigma, 'real') and assume(Ct, 'real') if you wanted, you'd get an answer parameterized by R_.
The solution is to find the null space of the matrix (P-I)', as for the previous problem.
null((P-I)')
ans =
-sigma/(sigma - 1)
1
Now if your vector Z became different from 0, you would need to add the particular solution, that is Z/(P-I). In the present case, it gives:
Z/(P-I)
Warning: System is rank deficient. Solution is not unique.
ans =
[ 0, 0]
This means that in this case the particular solution is [0 0], and the result of null gives you the homogeneous solution. Remember that the complete solution of a linear system of equations is the sum of the particular solution + a linear combination of the elements of the null space. A way to express this in Matlab could be:
syms lambda real;
sol = Z/(P-I) + lambda * null((P-I)')'
sol =
[ -(lambda*sigma)/(sigma - 1), lambda]
How can I solve a system of this kind in matlab?:
a + b + c = 0
a + d + e = 0
...etc
where each of this symbolic variables (they are previously defined with "syms") is in R^3,
for example:
a = [0 R1 R2];
b = [0 R3*cos(alpha) R3*sin(alpha)];
...etc (R1, R2, R3, .. are also symbolic variables, but one dimensional, ie: scalars)
I did search a lot but everyone solves systems of scalars, not of vectors.
In this case every vector equation represents 3 scalar equations
I know I could reformat the whole system into a matrix and solve Ax=0 but that would be a lot of work since these are 39 equations.
Thank you very much
I am trying to write a Matlab program that accepts variables for a system from the user, but there are more variables than system parameters. To be specific, six variables in three equations:
w - d - M = 0
l - d - T = 0
N - T + M = 0
This could be represented in matrix form as A*x=0 where
A = [1 0 0 -1 0 -1;
0 1 0 -1 -1 0;
0 0 1 0 -1 1];
x = [w l N d T M]';
I would like to be able to solve this system given a known subset of the variables. For example, if the user gives d, T, M, then the system is trivially solved for the other three variables. If the user supplies w, N, M, then it becomes a solvable 3-DOF system. And so on. (If the user over- or under-specifies the system then an error may of course result.)
Given any one of these combinations it's simple to (a priori) use matrix algebra to calculate the unknown quantities. But I don't know how to solve the general case, aside from using the symbolic toolbox (which I prefer not to do for compatibility reasons).
When I started with this approach I thought this step would be easy, but my linear algebra is rusty; am I missing something simple?
First, let x be a vector with NaN for the unknown values. This allows you to use ISNAN to find the indeces of the unknowns. If you calculate A*x for only the user-specified terms, that gives you a column of constants b. Take those constants to the right-hand side of the equation, and you have an equation of the form A*x = -b.
A = [1 0 0 -1 0 -1;
0 1 0 -1 -1 0;
0 0 1 0 -1 1];
idx = ~isnan(x);
b = A(:,idx)*x(idx); % user provided constants
z = A(:,~idx)\(-b); % solution of Ax = -b
x(~idx) = z;
With input x = [NaN NaN NaN 1 1 1]', for instance, you get the result [2 2 0 1 1 1]'. This uses MLDIVIDE, I'm not well versed enough in linear algebra to know whether PINV or something else would be better.
Given the linear system
A = [1 0 0 -1 0 -1;
0 1 0 -1 -1 0;
0 0 1 0 -1 1];
A*x = 0
Where the elements of x are identified as:
x = [w l N d T M]';
Now, suppose that {d,T,M} have known, fixed values. What we need are the indices of these elements in x. We've chosen the 4th, 5th and 6th elements of x to be knowns.
known_idx = [4 5 6];
unknown_idx = setdiff(1:6,known_idx);
Now, let me pick some arbitrary numbers for those known variables.
xknown = [1; -3; 7.5];
We will partition A into two submatrices, corresponding to the known and unknown variables.
Aknown = A(:,known_idx);
Aunknown = A(:,unknown_idx);
Now, move the known values to the right hand side of the equality, and solve. See that Aknown is a 3x3 matrix, so the problem is (hopefully) well posed.
xunknown = Aunknown\(-Aknown*xknown)
xunknown =
-8.5
2
10.5
Combine it all into the final solution.
x = zeros(6,1);
x(known_idx) = xknown;
x(unknown_idx) = xunknown;
x =
-8.5
2
10.5
1
-3
7.5
Note that I've expanded this all out into a few lines to show what is happening more clearly. But I could have done it all in just a line or two of code had I wanted to be parsimonious.
Finally, see that had I chosen some other sets of numbers to be the knowns, such as {l,d,T}, then the resulting system would be singular. So you must watch for that event. A test on the rank of Aunknown might be useful to weed out the problems. Or you might choose to employ pinv to build the solution.
The system of equations is fixed? What if you store the variables present in your three equations in a list per equation:
(w, d, M)
(l, d, T)
(N, T, M)
Then you get the user input and you can calculate the number of variables given in each equation:
User input: w, N, M
Given variables:
(w, d, M) -> 2
(l, d, T) -> 0
(N, T, M) -> 1
This would trivially give you d from the first equation. Therefore you end up with two equations containing two variables and you know you the equation system you have to solve.
It's basically your own simple symbolic solver for a single system of equations.