Simplify symbolic expression for optimized code generation
1 vue (au cours des 30 derniers jours)
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.
0 commentaires
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
Maybe because 1/2 is not a variable. How about this?
X_eq = collect(2*expand(X_eq),dt)/2;
Voir également
Catégories
En savoir plus sur Formula Manipulation and Simplification dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!