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?

 채택된 답변

Walter Roberson
Walter Roberson 2020년 12월 21일
F = matlabFunction(lhs(Eqn)-rhs(Eqn), 'vars', {[T2, T3, T4, T5, T6] })

댓글 수: 6

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.
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.
Thank you very much for your wonderuful explantion and taking your time to do. I understand better now.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

David Hill
David Hill 2020년 12월 21일
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

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'.".

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Symbolic Math Toolbox에 대해 자세히 알아보기

제품

태그

질문:

2020년 12월 21일

댓글:

2020년 12월 24일

Community Treasure Hunt

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

Start Hunting!

Translated by