How can I make function expression automatically

Hello Matlab experts,
I have a 5x1 symbolic named "Eq" with following expressions in it, with 5 unknown variables, T2, T3, T4, T5, T6.
- 0.5*T2^2 - 0.167*T2*T3 - 32.0*T2 - 0.0833*T3^2 + 1.5*T3 - 2610.0 == 0.0
- 0.0833*T2^2 - 0.167*T2*T3 + 0.5*T2 - 0.5*T3^2 - 0.167*T3*T4 - 2.0*T3 - 0.0833*T4^2 + 1.5*T4 == 0.0
- 0.0833*T3^2 - 0.167*T3*T4 + 0.5*T3 - 0.5*T4^2 - 0.167*T4*T5 - 2.0*T4 - 0.0833*T5^2 + 1.5*T5 == 0.0
- 0.0833*T4^2 - 0.167*T4*T5 + 0.5*T4 - 0.5*T5^2 - 0.167*T5*T6 - 2.0*T5 - 0.0833*T6^2 + 1.5*T6 == 0.0
- 0.0833*T5^2 - 0.167*T5*T6 + 0.5*T5 - 0.25*T6^2 - 0.5*T6 - 5.0 == 0.0
To use fsolve, I need to change them into the following expressions, with changing T2 -> T(1), T3 -> T(2), T4 -> T(3), T5 -> T(4), T6 -> T(5).
F(1) = - 0.5*T(1)^2 - 0.167*T(1)*T(2) - 32.0*T(1) - 0.0833*T(2)^2 + 1.5*T(2) - 2610.0;
F(2) = - 0.0833*T(1)^2 - 0.167*T(1)*T(2) + 0.5*T(1) - 0.5*T(2)^2 - 0.167*T(2)*T(3) - 2.0*T(2) - 0.0833*T(3)^2 + 1.5*T(3);
F(3) = - 0.0833*T(2)^2 - 0.167*T(2)*T(3) + 0.5*T(2) - 0.5*T(3)^2 - 0.167*T(3)*T(4) - 2.0*T(3) - 0.0833*T(4)^2 + 1.5*T(4);
F(4) = - 0.0833*T(3)^2 - 0.167*T(3)*T(4) + 0.5*T(3) - 0.5*T(4)^2 - 0.167*T(4)*T(5) - 2.0*T(4) - 0.0833*T(5)^2 + 1.5*T(5);
F(5) = - 0.0833*T(4)^2 - 0.167*T(4)*T(5) + 0.5*T(4) - 0.25*T(5)^2 - 0.5*T(5) - 5.0;
Is there any way to change without changing one by one manually?

 Respuesta aceptada

Walter Roberson
Walter Roberson el 21 de Dic. de 2020
F = matlabFunction(lhs(Eqn)-rhs(Eqn), 'vars', {[T2, T3, T4, T5, T6] })

6 comentarios

Thank you for your suggestion. I followed this, however it didn't work. The following is how I did. Do you have any other suggestions?
clc;
fun = @root5d_03;
x0 = [0,0,0,0,0];
x = fsolve(fun,x0)
function F = root5d_03(T)
syms T2 T3 T4 T5 T6
Eqn = [
- 0.5*T2^2 - 0.167*T2*T3 - 32.0*T2 - 0.0833*T3^2 + 1.5*T3 - 2610.0 == 0.0;
- 0.0833*T2^2 - 0.167*T2*T3 + 0.5*T2 - 0.5*T3^2 - 0.167*T3*T4 - 2.0*T3 - 0.0833*T4^2 + 1.5*T4 == 0.0;
- 0.0833*T3^2 - 0.167*T3*T4 + 0.5*T3 - 0.5*T4^2 - 0.167*T4*T5 - 2.0*T4 - 0.0833*T5^2 + 1.5*T5 == 0.0;
- 0.0833*T4^2 - 0.167*T4*T5 + 0.5*T4 - 0.5*T5^2 - 0.167*T5*T6 - 2.0*T5 - 0.0833*T6^2 + 1.5*T6 == 0.0;
- 0.0833*T5^2 - 0.167*T5*T6 + 0.5*T5 - 0.25*T6^2 - 0.5*T6 - 5.0 == 0.0
];
F = matlabFunction(lhs(Eqn)-rhs(Eqn), 'vars', {[T2, T3, T4, T5, T6] });
end
clc;
fun = root5d_03();
x0 = [0,0,0,0,0];
Opts = optimoptions('fsolve', 'MaxFunctionEvaluations', 1e5, 'MaxIterations', 1e5);
x = fsolve(fun, x0, Opts)
No solution found. fsolve stopped because the last step was ineffective. However, the vector of function values is not near zero, as measured by the value of the function tolerance.
x = 1×5
-35.8879 25.4902 -12.5355 3.4835 1.8599
syms T2 T3 T4 T5 T6
G = fun([T2,T3,T4,T5,T6]);
sol = solve(G([1 2 3 5]), [T2, T3, T4, T6]);
G5 = subs(G(5), sol);
sol5 = arrayfun(@solve, G5, 'uniform', false);
sols = arrayfun(@(K) subs([sol.T2(K), sol.T3(K), sol.T4(K), sol5{K}, sol.T6(K)], T5, sol5{K}), 1:length(sol5), 'uniform', 0);
exact_sols = vertcat(sols{:})
exact_sols = 
approx_sols = vpa(exact_sols, 5)
approx_sols = 
x0 = [1+1i, 1+1i, 1+1i, 1, 1+1i];
x_try_again = fsolve(fun, x0, Opts)
Equation solved. fsolve completed because the vector of function values is near zero as measured by the value of the function tolerance, and the problem appears regular as measured by the gradient.
x_try_again = 1×5
-36.4407 +61.7987i 27.9512 + 4.7923i -7.9052 + 5.1705i 2.2224 + 3.7204i -0.8355 + 2.2099i
function F = root5d_03(T)
syms T2 T3 T4 T5 T6
Eqn = [
- 0.5*T2^2 - 0.167*T2*T3 - 32.0*T2 - 0.0833*T3^2 + 1.5*T3 - 2610.0 == 0.0;
- 0.0833*T2^2 - 0.167*T2*T3 + 0.5*T2 - 0.5*T3^2 - 0.167*T3*T4 - 2.0*T3 - 0.0833*T4^2 + 1.5*T4 == 0.0;
- 0.0833*T3^2 - 0.167*T3*T4 + 0.5*T3 - 0.5*T4^2 - 0.167*T4*T5 - 2.0*T4 - 0.0833*T5^2 + 1.5*T5 == 0.0;
- 0.0833*T4^2 - 0.167*T4*T5 + 0.5*T4 - 0.5*T5^2 - 0.167*T5*T6 - 2.0*T5 - 0.0833*T6^2 + 1.5*T6 == 0.0;
- 0.0833*T5^2 - 0.167*T5*T6 + 0.5*T5 - 0.25*T6^2 - 0.5*T6 - 5.0 == 0.0
];
F = matlabFunction(lhs(Eqn)-rhs(Eqn), 'vars', {[T2, T3, T4, T5, T6] });
end
The x_try_again shows that fsolve thinks it comes up with an answer when given an initial value that includes complex coefficients. But I notice that the T5 coefficient especially is different than anything I find analytically, so it would be wise to cross-check the fsolve solution. It would probably be a good idea to cross-check the analytic solution too.
Johnny Yoon
Johnny Yoon el 23 de Dic. de 2020
Thank you for the wonderful solution. I didn't expect that it gives imaginary numbers. Would you mind if I ask you some questions regarding that? Why is the substraction "lhs(Eqn)-rhs(Eqn)" needed? Can just be replaced simply "Eqn"?
Is there any name for the math solving method that gave the solution that you wrote after you used fsolve?
When you have == in there, and you attempt to evaluate the expression with numeric coefficients, then the result of the == will either be 1 (bit-for-bit equality of the two terms) or 0 (one or more bits is different between the two terms.) fsolve() is looking for a zero return from the expressions, and the very first time it evaluated and found that the two sides were not equal (because the proposed values were wrong) it would return 0, which fsolve would consider to mean success.
What you need instead is hints to fsolve as to which direction to move the trial points. fsolve() takes numeric derivative estimates based upon the trial location and the results it gets back from the function, and that gives it information about which direction to project the trial point towards, using a Newton-Raphson type approach. You want the function to give a quite negative or quite positive result where the trial point is too far on one side or the other of the actual balancing. When you have A==B then A-B == B-B -> A-B == 0 is true, and conversely the result is positive if you have too much A value and not enough B value and negative if you have too much B value and not enough A value, which is information that fsolve() can use for its mathematical projections.
The symbolic approach I used was just standard stepwise refinement. Solve one equation for one variable, substituted the solved variable into the remaining equations, solve one of the mutated equations for one variable, substitute the solved variable into the mutated equations, and so on, iterating until you get to the point where you have either solved everything analytically, or have demonstrated that there is a problem, or have reduced down to equations that you can solve numerically.
MATLAB should be able to solve the entire set of equations without stepwise refinement, but to be honest, the symbolic solver is weak on working with polynomials of higher degree and sometimes you have to focus its attention.
Johnny Yoon
Johnny Yoon el 24 de Dic. de 2020
Thank you very much for your wonderuful explantion and taking your time to do. I understand better now.

Iniciar sesión para comentar.

Más respuestas (1)

David Hill
David Hill el 21 de Dic. de 2020
Did you look at the subs() function?
subs(Eq,T2,T(1));
subs(Eq,T3,T(2));
subs(Eq,T4,T(3));
subs(Eq,T5,T(4));
subs(Eq,T6,T(5));

1 comentario

Johnny Yoon
Johnny Yoon el 22 de Dic. de 2020
Thank you for your suggestion. Matlab consider T(1) as an element in T. So, it gives an error message "Unrecognized function or variable 'T'.".

Iniciar sesión para comentar.

Categorías

Más información sobre Symbolic Math Toolbox en Centro de ayuda y File Exchange.

Productos

Etiquetas

Preguntada:

el 21 de Dic. de 2020

Comentada:

el 24 de Dic. de 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by