Simplify symbolic expression for optimized code generation
Afficher commentaires plus anciens
I'm trying to generate optimized c code (reduce the number of operations) from symbolic MATLAB expressions. However I MATLAB doesn't seem to want to simplify even the simplest equations.
lets take the following expression as an example:
X_eq = [
q0 + (dt*q1*(gyrobx - omegax))/2 + (dt*q2*(gyroby - omegay))/2 + (dt*q3*(gyrobz - omegaz))/2;
q1 - (dt*q0*(gyrobx - omegax))/2 + (dt*q3*(gyroby - omegay))/2 - (dt*q2*(gyrobz - omegaz))/2;
q2 - (dt*q0*(gyroby - omegay))/2 - (dt*q3*(gyrobx - omegax))/2 + (dt*q1*(gyrobz - omegaz))/2;
q3 + (dt*q2*(gyrobx - omegax))/2 - (dt*q1*(gyroby - omegay))/2 - (dt*q0*(gyrobz - omegaz))/2];
What i'm looking for is (basically factor out dt and (1/2)):
X_eq = [
q0 + (((q1*(gyrobx - omegax)) + (q2*(gyroby - omegay)) + (q3*(gyrobz - omegaz)))*dt)/2;
q1 - (((q0*(gyrobx - omegax)) + (q3*(gyroby - omegay)) - (q2*(gyrobz - omegaz)))*dt)/2;
q2 - (((q0*(gyroby - omegay)) - (q3*(gyrobx - omegax)) + (q1*(gyrobz - omegaz)))*dt)/2;
q3 + (((q2*(gyrobx - omegax)) - (q1*(gyroby - omegay)) - (q0*(gyrobz - omegaz)))*dt)/2];
simplify(X_eq, 'steps', 100) returns the original expression so it's useless:
ans =
q0 + (dt*q1*(gyrobx - omegax))/2 + (dt*q2*(gyroby - omegay))/2 + (dt*q3*(gyrobz - omegaz))/2
q1 - (dt*q0*(gyrobx - omegax))/2 + (dt*q3*(gyroby - omegay))/2 - (dt*q2*(gyrobz - omegaz))/2
q2 - (dt*q0*(gyroby - omegay))/2 - (dt*q3*(gyrobx - omegax))/2 + (dt*q1*(gyrobz - omegaz))/2
q3 + (dt*q2*(gyrobx - omegax))/2 - (dt*q1*(gyroby - omegay))/2 - (dt*q0*(gyrobz - omegaz))/2
collect(X_eq, [dt]) returns the following which is a step forward but doesn't factorize (1/2):
ans =
((q1*(gyrobx - omegax))/2 + (q2*(gyroby - omegay))/2 + (q3*(gyrobz - omegaz))/2)*dt + q0
((q3*(gyroby - omegay))/2 - (q0*(gyrobx - omegax))/2 - (q2*(gyrobz - omegaz))/2)*dt + q1
((q1*(gyrobz - omegaz))/2 - (q3*(gyrobx - omegax))/2 - (q0*(gyroby - omegay))/2)*dt + q2
((q2*(gyrobx - omegax))/2 - (q1*(gyroby - omegay))/2 - (q0*(gyrobz - omegaz))/2)*dt + q3
Finally, collect(X_eq, [1/2, -1/2, dt, -dt]) does the following which comes close but is still not what I expect:
ans =
((q1*(gyrobx - omegax) + q2*(gyroby - omegay) + q3*(gyrobz - omegaz))*dt)/2 + q0
((q3*(gyroby - omegay))*dt)/2 - ((q0*(gyrobx - omegax) + q2*(gyrobz - omegaz))*dt)/2 + q1
((q1*(gyrobz - omegaz))*dt)/2 - ((q0*(gyroby - omegay) + q3*(gyrobx - omegax))*dt)/2 + q2
((q2*(gyrobx - omegax))*dt)/2 - ((q1*(gyroby - omegay) + q0*(gyrobz - omegaz))*dt)/2 + q3
I've tried subexpr() as well which has it's used by doesn't help me in this situation. The number of equations is high so finding an automated way of reducing the number of calculations is important.
Réponses (1)
Andrew Newell
le 17 Avr 2017
I don't know how particular you are about the exact form of the simplified expression, but this certainly produces a simpler expression:
Q = [q0; q1; q2; q3];
X_eq = Q + simplify(expand(X_eq-Q));
5 commentaires
Andrew Newell
le 17 Avr 2017
It's also worth pointing out that you could substitute
x = gyrobx-omegax
etc. to greatly simplify the expressions.
Ehsan Tofigh
le 17 Avr 2017
Andrew Newell
le 17 Avr 2017
Yes, simplify often doesn't do what we expect it to do. Hard to know what to suggest since I don't know how your equations depart from this form.
Ehsan Tofigh
le 17 Avr 2017
Andrew Newell
le 17 Avr 2017
Maybe because 1/2 is not a variable. How about this?
X_eq = collect(2*expand(X_eq),dt)/2;
Catégories
En savoir plus sur Programming dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!