Solving unknowns of a matrix in Matlab - matlab

I have a list of formula stored in a cell array, and I solve the unknowns within the matrix.
For example, consider a 2*2 matrix:
[2x+y, 4q+z; 3x+0.5y, 2q+12z ]
How to solve q,x,y,z by setting each cell equals 20? (i.e., q= 4, x =5, y = 10, z=1)

You're asking to solve a linear system. The canonical way to write a linear system is as A*x = b where A is a matrix, x is the vector to solve for, and b is also a vector. Writing your problem (in math) using matrices, the system is:
[0 2 1 0 [q [20
4 0 0 1 * x = 20
0 3 .5 0 y 20
2 0 0 12] z] 20]
To solve the system numerically in MATLAB:
A = [0, 2, 1, 0; 4, 0, 0, 1;, 0, 3, .5, 0; 2, 0, 0, 12];
b = [20; 20; 20; 20];
xsol = linsolve(A, b);
You could also do xsol = A \ b. A point of caution: both linsolve and \ will solve the system in the least squares sense if the system is overdetermined (typically, system is overdetermined if A is m by n where m > n).
xsol(1) will give the value for q, xsol(2) will give value for x, etc...
Solution is [4.7826; 5.0000; 10.0000; 0.8696]

One way to achieve what you are looking for is to use the Symbolic Toolbox. Here is an example code to solve for q, x, y, and z.
syms q x y z
A = [2*x+y==20, 4*q+z==20; 3*x+0.5*y==20, 2*q+12*z==20];
S = solve(A,[q x y z]);
disp([S.q S.x S.y S.z]);
Output:
[110/23, 5, 10, 20/23]

Related

Summation in Matlab without for/while loop

How Do i solve this summation in MATLAB without using for/while loop?
Here C is a vector(1*N matrix), n=length(c) and x is scalar.
c(1)*x^1+c(2)*x^2+c()*x^3+....+c(n)*x^n.
Or can i Create a matrix with all element equal to x but with increasing power, like x, x^2,x^3....?
There are several ways:
result = polyval(fliplr([0 c]), x);
result = sum(c.*x.^(1:numel(c)));
result = sum(c.*cumprod(repmat(x, 1, numel(c))));
As an example, for
c = [3 4 -5 2 3];
x = 9;
any of the above gives
result =
186975
Check:
>> c(1)*x^1+c(2)*x^2+c(3)*x^3+c(4)*x^4+c(5)*x^5
ans =
186975

Gcd of polynomials modulo k

I want to ask Matlab to tell me, for example, the greatest common divisor of polynomials of x^4+x^3+2x+2 and x^3+x^2+x+1 over fields like Z_3[x] (where an answer is x+1) and Z_5[x] (where an answer is x^2-x+2).
Any ideas how I would implement this?
Here's a simple implementation. The polynomials are encoded as arrays of coefficients, starting from the lowest degree: so, x^4+x^3+2x+2 is [2 2 0 1 1]. The function takes two polynomials p, q and the modulus k (which should be prime for the algorithm to work property).
Examples:
gcdpolyff([2 2 0 1 1], [1 1 1 1], 3) returns [1 1] meaning 1+x.
gcdpolyff([2 2 0 1 1], [1 1 1 1], 5) returns [1 3 2] meaning 1+3x+2x^2; this disagrees with your answer but I hand-checked and it seems that yours is wrong.
The function first pads arrays to be of the same length. As long as they are not equal, is identifies the higher-degree polynomial and subtracts from it the lower-degree polynomial multiplied by an appropriate power of x. That's all.
function g = gcdpolyff(p, q, k)
p = [p, zeros(1, numel(q)-numel(p))];
q = [q, zeros(1, numel(p)-numel(q))];
while nnz(mod(p-q,k))>0
dp = find(p,1,'last');
dq = find(q,1,'last');
if (dp>=dq)
p(dp-dq+1:dp) = mod(p(1+dp-dq:dp) - q(1:dq), k);
else
q(dq-dp+1:dq) = mod(q(dq-dp+1:dq) - p(1:dp), k);
end
end
g = p(1:find(p,1,'last'));
end
The names of the variables dp and dq are slightly misleading: they are not degrees of p and q, but rather degrees + 1.

Matlab Combine Row Vectors into one row

Is there a vectorized, automated way to fill a row vector l times with repeating numbers x such that x is increased by y after a certain number k of elements? k, l, x, and y are given.
Two examples:
(k = 4, l = 4, x = 0, y = 1): $A = [0 0 0 0; 1 1 1 1; 2 2 2 2; 3 3 3 3];$
(k = 2, l = 3, x = 0, y = 0.1): $B = [0 0; 0.1 0.1; 0.2 0.2]$
You can use repmat together with a:b
This way your fist example would look like this:
repmat((0:3)', 1,4)
The second one:
repmat((0:0.1:0.2)', 1,2)
You can also try linspace or similar functions to be as close to what you want as possible

equationsToMatrix: how do I get the values of the variables?

When using equationsToMatrix you solve a set of linear equations as in the example (the solution is included)
syms x y z;
[A, b] = equationsToMatrix([x + y - 2*z == 0, x + y + z == 1, 2*y - z + 5 == 0], [x, y, z])
%solution of the equation set
A =
[ 1, 1, -2]
[ 1, 1, 1]
[ 0, 2, -1]
b =
0
1
-5
The vector b returns the values of the variables at issue: x,y, and z. However if I type x then MATLAB returns x and not 0, which is the solution of the equation in this case. This also occurs without adding the syms option.
The other problem is that if I type b(1) or b(2), I don't get any value: I would expect b to contain the values of x,y and z.
What I would need is to get something like this in the end
b(1) = 0
or
x = 0
What should I do to get the values of x,y,z by just typing x,y,z?
What you have is a way of converting symbolic linear equations into a numeric system by extracting the coefficient matrices. To solve the system you need to do
sol = A\b;
and now you can use the values in another expression with
subst(expr, {x,y,z}, {sol(1),sol(2),sol(3));
for example
A =
1 1 -2
1 1 1
0 2 -1
b =
0
1
-5
>> A\b
ans =
3.0000
-2.3333
0.3333

Partition a matrix into several matrices

How can I partition a matrix into several smaller matrices to find unknown variables?
For example, given:
how can solve this problem by partitioning (splitting) a matrix 3x3 into smaller matrices (1x1 or other) to find the values of x, y, z and u?
Your matrix dimensions dont agree, or am I missing something?
Edit:
The code from Jeff E will work fine on smaller matrices.
For bigger matrices you will need to use backward substitution or some other algorithm, mainly because matrix inversion is a memory intensive task.
In the new image, you isolate for the unknown matrix using some identities:
A * X = B
(inv(A)) * A * X = (inv(A)) * B
I * X = (inv(A)) * B
X = (inv(A)) * B
In Matlab:
A = [1, 2; 0, 1]
B = [4, 7; 4, 6]
X = inv(A) * B
Output:
ans =
-4 -5
4 6
To solve an equation of the form A*X=B, you should use the backslash operator, since explicitly taking the inverse should be avoided if possible
A = [1, 2; 0, 1];
B = [4, 7; 4, 6];
X = A\B
X =
-4 -5
4 6