Simplify symbolic expression for optimized code generation
2 ビュー (過去 30 日間)
古いコメントを表示
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 件のコメント
回答 (1 件)
Andrew Newell
2017 年 4 月 17 日
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 件のコメント
Andrew Newell
2017 年 4 月 17 日
Maybe because 1/2 is not a variable. How about this?
X_eq = collect(2*expand(X_eq),dt)/2;
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!