diff function rearranges symbolic expression leading to non-vanishing terms
Show older comments
I am trying to feedback linearize my non-linear system in Matlab. To that end I have to represent it in the following form:

So after I have modeled my system in the form of nonlinear differential equations,
, I use the diff function to take the derrivative with respect to u to aquire g
, and
. This works, of course only if the system can be represented in the mentioned form. However, the diff function rewrites some of my expressions, which then after subtraction lead to non-vanishing factors multiplying u. For example, my input is still present in
multiplied with a factor 5.7024e-18. I suspect, there is some quantization error introduced due to diff re-writing the derivative
. Can this be somehow avoided?
, I use the diff function to take the derrivative with respect to u to aquire g
, and
. This works, of course only if the system can be represented in the mentioned form. However, the diff function rewrites some of my expressions, which then after subtraction lead to non-vanishing factors multiplying u. For example, my input is still present in
multiplied with a factor 5.7024e-18. I suspect, there is some quantization error introduced due to diff re-writing the derivative
. Can this be somehow avoided? g_x=[diff(dxdt,[Q_g]) diff(dxdt,[Q_b])];
for i=1:size(g_x,1)
i
f_x(i,:)=simplify(dxdt(i,:)-g_x(i,1)*Q_g-g_x(i,2)*Q_b,'steps',10,'IgnoreAnalyticConstraints',true);
end
Here Q_g and Q_b are my inputs.
An example of the re-writing of expressions:
dxdt = - (1297036692682702848*Q_b*(C_carbv - 47/20000))/15694143981460705 + ..................
g_x=1905022642377719808/9808839988412940625 - (1297036692682702848*C_carbv)/15694143981460705
f_x=Q_b*((1297036692682702848*C_carbv)/15694143981460705 - 1905022642377719808/9808839988412940625) - (1297036692682702848*Q_b*(C_carbv - 47/20000))/15694143981460705 + ..............................
simplify(Q_b*((1297036692682702848*C_carbv)/15694143981460705 - 1905022642377719808/9808839988412940625) - ...
(1297036692682702848*Q_b*(C_carbv - 47/20000))/15694143981460705)
ans =
(47*Q_b)/8242150268041428750
The .................. stands for terms that do not depend on Q_b.
2 Comments
Paul
on 16 Jun 2021
Can you provide complete code that can be replicated that illustrates the problem and is prefably as simplie as possible?
Martin Elenkov
on 16 Jun 2021
Edited: Martin Elenkov
on 16 Jun 2021
Accepted Answer
More Answers (1)
This is a floating point problem, but it comes when MATLAB takes your constants and turns them into symbolic numbers. Do you see all of those large integers? For example...
X = sym(1.34536363425474)
But that ratio is not exactly the same value as the original number. It is typically a close approximation.
vpa(X,40)
So you get trash in there, down in digit 17 and below.
My question is, why is this a problem?
4 Comments
Walter Roberson
on 16 Jun 2021
When you have a floating point value involved in a symbolic expression, then by default MATLAB converts it using 'r' option.
The 'r' option asks the symbolic toolbox to take the floating point number and run a series of approximations and return one of:
- a simple rational multiple of πwith a denominator no greater than 100000 (most larger denominators will not be detected)
- a simple rational multiple of a sqrt() of a rational integer; when the denominator starts getting larger than about 315 then it starts occasionally missing the possibility that the number can be expressed this way
- or, if need be, a rational number
In each case, numbers that are very close to the above will be approximated as being exactly one of the above. For example sym(pi*(1-100*eps)) will be approximated as πexactly but sym(pi*(1-101*eps)) will not be
If you have a general number that has no obvious structure, such as the 1.34536363425474 that John mentions, then most of the time it is going to be expressed as a rational with large denominator.
You can, however, use sym() yourself to ask to transform a floating point number to symbolic in a different way. The most common way to do that is to use
sym(NUMBER, 'd')
This does not do any approximation. Instead, it takes the exact floating point binary representation, and converts it into decimal according to the current digits setting -- so for example sym(1/6,'d') is not going to show up as 1.666 with the 6 repeated until the end, but will instead show up like 0.1666666666666666574148081281237 because 1/6 had to be approximated to store as floating point, and it is the approximated value that is converted.
You can also use sym(NUMBER, 'f')
This does not do any approximation: instead it takes the floating point representation in binary and expresses it as a rational, like 6004799503160661/36028797018963968 ... remembering that 1/6 has no exact finite binary representation
Sometimes what you end up wanting to do is
vpa(sym(NUMBER))
so for example sym(1/6) invokes the default 'r' rational approximation to find the symbolic rational number 1/6 and then vpa() can approximate that into decimal for as many decimal places as needed. Likewise vpa(sym(1.57)) has the sym(1.57) find the rational approximation 157/100 and then vpa() of that expresses it as symbolic floating point 1.57
And sometimes it is best to just sym() of a quoted number, such as
sym('1.34536363425474')
to get the same decimal number out as software floating point.
Martin Elenkov
on 16 Jun 2021
Edited: Martin Elenkov
on 16 Jun 2021
simplify() asks to rewrite the expression to combine parts if it can figure out how. When it does that, the combined portions mostly lose the information about the number of digits the symbolic floating point numbers were evaluated at
syms Q_b C_carbv
f_x = Q_b * (vpa(83.0,2)*C_carbv - vpa(0.19,2)) - vpa(83.0,2)*Q_b*(C_carbv - vpa(2.3e-3,2))
expand(f_x)
Makes sense to me, since - 0.19 is not - 2.3e-3
collect(f_x, Q_b)
Martin Elenkov
on 16 Jun 2021
Edited: Martin Elenkov
on 16 Jun 2021
Categories
Find more on Mathematics in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
