Numerical solutions of a nonlinear equation with different independent values in matlab - matlab

For example, if I have this function: g = t^3 - 5*t^2 + 2
And g = [3 4 6 2 9 10 17 1]
I would like to solve the equation for each g[i] and obtain the resulting t vector.

This might guide you:
>> syms t g %// define symbolic variables
>> y = t^3 - 5*t^2 + 2 - g; %// define y so that equation is: y=0
>> g_data = [3 4 6 2 9 10 17 1]; %// define g values
>> n = 1; %// choose first value. Or use a loop: for n = 1:numel(g_data)
>> s = solve(subs(y, g, g_data(n))) %// substitute g value and solve equation y=0
s =
25/(9*((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)) + ((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3) + 5/3
5/3 - ((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)/2 - 25/(18*((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)) - (3^(1/2)*(25/(9*((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)) - ((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3))*i)/2
5/3 - ((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)/2 - 25/(18*((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)) + (3^(1/2)*(25/(9*((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3)) - ((108^(1/2)*527^(1/2))/108 + 277/54)^(1/3))*i)/2
>> double(s) %// show solutions as floating point values
ans =
5.039377328113847
-0.019688664056924 + 0.445027607060817i
-0.019688664056924 - 0.445027607060817i

Related

Finding minimizers numerically in Matlab with 'fsolve'

I'm completely new to Matlab and I've been having some problems with my code.
I need to use 'fsolve' to locate minimizers to a nonlinear optimization problem, but I can't get it to work.
I've been using the 'Solution Process of Nonlinear System' part from mathworks.
My code is the following:
function F = myfun(x)
F = [4*x(4) + 2*x(1) - x(3)*(2*x(1) + 4) + 4*x(1)*(x(1).^2 + x(2) - 11) + 2*x(2).^2 - 14;
x(3) - 10*x(4) + 2*x(2) + 4*x(2)*(x(2).^2 + x(1) - 7) + 2*x(1).^2 - 22;
x(2) - (x(1) + 2).^2;
4*x(1) - 10*x(2);];
x0 = [-5;-5];
options = optimoptions('fsolve','Display','iter');
[x,fval] = fsolve(#myfun,x0,options);
end
Where it says that; the value assigned to x appears to be unused as well as; not enough input arguments. But accoring to the mathworks page, I've done the exact same thing as them, so I'm sort of lost now.
There are several things that you are not doing correctly:
The function myfun must only contain equations (as mentioned in Florian's comment).
fsolve, x0 and options must be called from a separate script or from the Command Window.
The initial point array x0 must have at least as many elements as variables (x(4), x(3), x(2), x(1)) present in the equations in myfun.
Edit your function myfun, make sure that it only contains equations and save it in your working directory.
function F = myfun(x)
F = [4*x(4) + 2*x(1) - x(3)*(2*x(1) + 4) + 4*x(1)*(x(1)^2 + x(2) - 11) + 2*x(2)^2 - 14;
x(3) - 10*x(4) + 2*x(2) + 4*x(2)*(x(2)^2 + x(1) - 7) + 2*x(1)^2 - 22;
x(2) - (x(1) + 2)^2;
4*x(1) - 10*x(2)];
end
Note that you don't need to use the element-wise power operator .^. Using the ^ operator will be enough to define powers in your equations.
Now in the Command Window enter the following instructions:
x0 = [-5;-5;-5;-5];
options = optimoptions('fsolve','Display','iter');
[x,fval] = fsolve(#myfun,x0,options);
Note that I modified x0 to have at least 4 elements in order to match the number of equations that you defined in myfun. These are just sample values, so you should modify x0 with the values of your problem.
This is a fragment of the output:
Norm of First-order Trust-region
Iteration Func-count f(x) step optimality radius
0 5 81521 4.27e+04 1
1 10 12608.5 1 1.15e+04 1
2 15 966.243 2.5 1.71e+03 2.5
3 20 408.322 6.25 685 6.25
4 21 408.322 15.625 685 15.6
5 26 263.815 3.90625 244 3.91
6 27 263.815 9.76563 244 9.77
7 32 205.88 2.44141 272 2.44
8 37 138.11 6.10352 206 6.1
9 42 93.4561 6.10352 105 6.1
10 47 64.0129 6.10352 42.3 6.1
...

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

Have a trouble with the function roots

Hey guys I have multiple problems with using function 'roots'.
I Have to find zeros of 's^1000 + 1'.
I made Y = zeros(1,1000) then manually changed the 1000th matrice to '1'. but then 'root' function does not work with it !
Another problem is that I am having trouble with matrix multiplication. The question is finding zeros(roots) of (s^6 + 6*s^5 + 15*s^4 + 20*s^3 + 15*s^2 + 6*s +1)*(s^6 + 6s^5 + 15*s^4 +15*s^2 +6*s +1) so i did:
a = [1 6 15 20 15 6 1]
b = [1 6 15 0 15 6 1]
y = a.*b;
roots(y)
but this gives me
-27.9355 + 0.0000i
-8.2158 + 0.0000i
0.1544 + 0.9880i
0.1544 - 0.9880i
-0.1217 + 0.0000i
-0.0358 + 0.0000i
where I calculate the original equation with wolfram then I have made matrix as :
p = [1 12 66 200 375 492 524 492 375 200 66 12 1]
roots(p)
and this gives me :
-3.1629 + 2.5046i
-3.1629 - 2.5046i
0.3572 + 0.9340i
0.3572 - 0.9340i
-1.0051 + 0.0000i
-1.0025 + 0.0044i
-1.0025 - 0.0044i
-0.9975 + 0.0044i
-0.9975 - 0.0044i
-0.9949 + 0.0000i
-0.1943 + 0.1539i
-0.1943 - 0.1539i
and I think the second solution is right (that is what wolfram alpha gave me)
How would you answer these two questions through matlab guys?
To multiply polynomials, you convolve their coefficients:
>> roots(conv(a,b))
ans =
-3.1629 + 2.5046i
-3.1629 - 2.5046i
0.3572 + 0.9340i
0.3572 - 0.9340i
-1.0051
-1.0025 + 0.0044i
-1.0025 - 0.0044i
-0.9974 + 0.0044i
-0.9974 - 0.0044i
-0.9950
-0.1943 + 0.1539i
-0.1943 - 0.1539i
Q1
Using roots to find the roots of s1000 + 1 is a bit of an overkill. The solution is given by this code snippet (corrected the first version; may be deduced using De Moivre's formula):
n = 1000;
k = 0:n-1
u = (2*k + 1)*pi / n;
s = cos(u) + 1i*sin(u)
Also, this method is approx. 100000 times faster.
Q2
Multiplying two polynomials to find the roots of their product is a bit of an overkill. :-) The union of the two polynomials' root sets is the root set of the product polynomial:
s = [roots(a);roots(b)]
Also, this method is more accurate.
1) The vector describing s^1000 + 1 should end with a 1 as well.
2)
a = [1 6 15 20 15 6 1]
b = [1 6 15 0 15 6 1]
y = a.*b;
This is a DOT product, multiplication of polynomials do not multiply element-wise.
Question 1
You need to include the coefficient of x^0 in the vector of coefficients, so there are 1001 entries with the first and last being 1
coeffs=zeros(1001,1);
coeffs([1,1001])=1;
roots(coeffs)
Question 2
To multiply the coefficients of polynomials you need to use convolution:
roots(conv(a,b))

Best way to solve an equation in form f(x)=K*u(x)

I am solving an equation of motion, which is described e.g. as
syms u1 u2 f3 f4;
K=magic(4);
f=[2 3 f3 f4];
u=[u1 u2 9 7];
where both f and K include variables.
Which is the easiest or/and most efficient way to do this? I want something like
solution=solve(f==K*u);
and don't know if it's the efficient way.
Your equations are not yet in standard form, yet are reducible to it.
Compute
>> syms u1 u2 f3 f4;
>> K = magic(4);
>> f = [2 3 f3 f4].';
>> u = [u1 u2 9 7].';
>> K*u - f
ans =
16*u1 + 2*u2 + 116
5*u1 + 11*u2 + 143
9*u1 + 7*u2 - f3 + 138
4*u1 + 14*u2 - f4 + 142
In which I altered the formatting for clarity. From this we can see that if we define
b = [-116 -143 -138 -142].';
A = [16 2 0 0
5 11 0 0
9 7 -1 0
4 14 0 -1];
Then we have an equation in standard form
A*X = b
where
X = [u1 u2 f3 f4].'
Then, it is a simple matter of
>> X = A\b
ans =
-5.963855421686747e+000 % u1
-1.028915662650603e+001 % u2
+1.230120481927711e+001 % f3
-2.590361445783132e+001 % f4

Matlab Vectorization : How to avoid this "for" loop?

I have following matrices :
X=1 2 3
Y=4 5 6
A=1 2 3
4 5 6
7 8 9
I Want to do
for each (i,j) in A
v = A(i,j)*X - Y
B(i,j) = v * v'
i.e. each element of A is multiplied by vector X, then resultant vector subtracts Y from itself and finally we take inner product of that vector to bring a single number.
Can it be done without for loop ?
One thing often forgotten in Matlab: The operator ' takes the conjugate transposed (.' is the ordinary transposed). In other words, A' == conj(trans(A)), whereas A.' == trans(A), which makes a difference if A is a complex matrix.
Ok, let's apply some mathematics to your equations. We have
v = A(i,j)*X - Y
B(i,j) = v * v'
= (A(i,j)*X - Y) * (A(i,j)*X - Y)'
= A(i,j)*X * conj(A(i,j))*X' - Y * conj(A(i,j))*X'
- A(i,j)*X * Y' + Y * Y'
= A(i,j)*conj(A(i,j)) * X*X' - conj(A(i,j)) * Y*X' - A(i,j) * X*Y' + Y*Y'
So a first result would be
B = A.*conj(A) * (X*X') - conj(A) * (Y*X') - A * (X*Y') + Y*Y'
In the case of real matrices/vectors, one has the identities
X*Y' == Y*X'
A == conj(A)
which means, you can reduce the expression to
B = A.*A * (X*X') - 2*A * (X*Y') + Y*Y'
= A.^2 * (X*X') - 2*A * (X*Y') + Y*Y'
An alternative method:
X = [1 2 3]
Y = [4 5 6]
A = [1 2 3; 4 5 6; 7 8 9]
V = bsxfun(#minus, A(:)*X, [4 5 6])
b = sum((V.^2)')
B = reshape(b , 3, 3)
I get the result:
B = 27 5 11
45 107 197
315 461 635