Simplify symbolic expression for optimized code generation
1 Ansicht (letzte 30 Tage)
Ältere Kommentare anzeigen
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 Kommentare
Antworten (1)
Andrew Newell
am 17 Apr. 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 Kommentare
Andrew Newell
am 17 Apr. 2017
Maybe because 1/2 is not a variable. How about this?
X_eq = collect(2*expand(X_eq),dt)/2;
Siehe auch
Kategorien
Mehr zu Symbolic Variables, Expressions, Functions, and Preferences finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!