diff function rearranges symbolic expression leading to non-vanishing terms
    9 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
    Martin Elenkov
 el 15 de Jun. de 2021
  
    
    
    
    
    Comentada: Martin Elenkov
 el 17 de Jun. de 2021
            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
, I use the diff function to take the derrivative with respect to u to aquire g , and
, 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
. 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
 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?
. Can this be somehow avoided? 
 , I use the diff function to take the derrivative with respect to u to aquire g
, I use the diff function to take the derrivative with respect to u to aquire g , and
, 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
. 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
 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?
. 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 comentarios
  Paul
      
      
 el 16 de Jun. de 2021
				Can you provide complete code that can be replicated that illustrates the problem and is prefably as simplie as possible?
Respuesta aceptada
  Paul
      
      
 el 16 de Jun. de 2021
        Why not just use collect() and coeffs() on the elements of dxdt?  If the system is affine in u, then those should give the desired result directly
syms x u1 u2
dxdt = x^2 + x + x*u1 + x^3*u1 + x^2*u2 + u2;
dxdt = collect(dxdt,[u1 u2])
[c,t] = coeffs(dxdt,[u1 u2])
fofx = c(find(t==1))
gofx = [c(find(t==u1)) c(find(t==u2))]
If the system is not affine in u, then extra terms will show up in t, so you can check numel(t) before doing any other processing to decide how to proceed.
dxdt = x^2 + x + x*u1 + x^3*u1 + x^2*u2 + u2 + u1*u2;
dxdt = collect(dxdt,[u1 u2])
[c,t] = coeffs(dxdt,[u1 u2])
5 comentarios
  Paul
      
      
 el 16 de Jun. de 2021
				I thought 'all' might also make it easier to determine if f(x) or an element of g(x) is zero. Alas, that appears to not be the case:
syms x u1 u2
dxdt = x*u1;
[c,t]=coeffs(dxdt,[u1 u2],'all')
So some logic will still be needed in a situation like this to set the appropriate element of g(x) to zero because u2 doesn't exist in t, even though it was explicitly requested, which is too bad for this use case.
Más respuestas (1)
  John D'Errico
      
      
 el 16 de Jun. de 2021
        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 comentarios
  Walter Roberson
      
      
 el 16 de Jun. de 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
 el 16 de Jun. de 2021
				
      Editada: Martin Elenkov
 el 16 de Jun. de 2021
  
			
		Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!





















