Open sekisushai opened 7 years ago
Having symbolic computation on mathematical expressions would certainly by very interesting... The thing is that the question (in general...) seems quite large:
do we only need a limited subset of simplifications? Only trigonometric simplifications ? Or a larger class of expressions?
what would be the criteria of simplifications ? I guess the "computation cost" of the resulting expression. Or "expression complexity " ? So we would have to characterize that. Is it enough? Do we need to think about other criteria like "calculation precision" (since we are using approximation of numbers when we compute with floats...) ?
can we develop something ourself? Or the problem is difficult enough to use an already existing system like for instance: GiNaC (https://www.ginac.de/tutorial/) or Simply (http://docs.sympy.org/latest/index.html) ?
Any insight would be welcome..
For my applications, the first criterion for simplification is the lowest computation cost. I guess it associated with the simplest mathematical expression.
In fact, some algorithms never compiles because of too complex expressions and high computation cost. If it compiles it is often very CPU consuming while a lot of terms could be computed with simpler mathematical expressions or are even 0 ('cos(ma.PI/2)', 'sin(ma.PI)', ...).
I have no idea how a symbolic computation system is integrable in Faust and at which point. But as for factorization, the compiler could maybe at least recognize some mathematical identities ..?
About precision, my thought is that symbolic form could help to gain a lot computation cost, especially with trigonometry. For example with the number 'PI'. If 'cos(ma.PI/2)' gives a true '0' (and not '6.123233995736766e-17' in double precision), it could simplify the output at compilation time, or if use in association with some sliders, it could be associated with the primitives ‘control' or ‘enable’ and save a some computations at execution time.
This is an interesting problem. I would try Wolfram Alpha for such simplifications, and after that, Mathematica or Maxima. My experience (mostly with Maxima and Macsyma before that) has been that the symbolic math programs do not do trig simplifications as well as a good math student after taking a trig class.
Analogous to the block diagrams in Faust, one needs a canonical form for every trig expression, over which "rewriting rules" (such as trigexpand() followed by trigsimp() in Maxima) are passed in order to apply simplifications such as cos^2 + sin^2 = 1. A problem is that the best final form is not obtainable using a fixed sequence of manipulations (in my past experience). It was necessary to choose the right fork in the road at the right point to get best results. I don't know if this situation has improved, but I doubt it. Maybe nowadays the right approach is to take all forks (a la Yogi Berra) and return the best result.
For some examples, see
http://maxima.sourceforge.net/docs/tutorial/en/gaertner-tutorial-revision/Pages/TrigTrans0001.htm
In principle, maxima could be integrated into Faust as a kind of "preprocessor", or some API could connect them.
On Mon, Jul 3, 2017 at 8:57 AM, sekisushai notifications@github.com wrote:
Hello,
I'm posting this issue -more as an feature request- about trigonometric simplifications.
For some applications, I manipulate trigonometric functions (spherical harmonics) and depending on the algorithm, the output formula could be very complicated.
However, in a lot of cases, trigonometric identities could help to simplify drastically the expressions.
For example, as pointed in this issue: https://github.com/grame-cncm/faust/issues/56 http://url, the algorithm outputs a matrix where all terms are functions which can be simplified in the majority of the cases. However, the output terms are not given in their simplest form, so far. For example, the term rot(2,1,1) in the algorithm described in the aforementioned issue gives:
rot(2,1,1) = cos(pitch)^2cos(roll)cos(yaw) + sin(pitch)(-cos(roll)cos(yaw)sin(pitch) + sin(roll)sin(yaw))
Which, after factorization gives rot(2,1,1) = cos(roll)cos(yaw)(cos(pitch)^2 - sin(pitch)^2)) + sin(pitch)sin(roll)sin(yaw) This latter expression is the output proposed by the compiler.
However, knowing that cos(pitch)^2 - sin(pitch)^2 = cos(2pitch) the previous expression could be simplified with: rot(2,1,1) = cos(roll)cos(yaw)cos(2pitch) + sin(pitch)sin(roll)sin(yaw) which is a simpler expression.
Following this example, I'm wondering if it is possible for the compiler to recognize trigonometric identities, typically as given in the following link: https://www.mathportal.org/formulas/pdf/trigonometry-formulas.pdf http://url
Thank you ! Pierre
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/grame-cncm/faust/issues/59, or mute the thread https://github.com/notifications/unsubscribe-auth/ACGVFcWWfy34Io2xEK3kIHq4vE4VddGuks5sKQF2gaJpZM4OMZF- .
--
Julius O. Smith III jos@ccrma.stanford.edu Professor of Music and, by courtesy, Electrical Engineering CCRMA, Stanford University http://ccrma.stanford.edu/~jos/ http://ccrma.stanford.edu/
Picking up this old issue, I second the idea of more advanced term rewriting for mathematical expressions. The extent to which you can do static optimization is one of the things I really like about functional language compilers and Faust use cases often require optimization of CPU cycles.
One particular thing I needed was the simplification of exp(log(x))
(resp. pow(a, log10(x))
) so I can normalize a frequency parameter given in Hz for va.moogLadder
without having to worry about precision loss and unnecessary calculations. But I can imagine other use cases that would benefit from this.
Hello,
I'm posting this issue -more as an feature request- about trigonometric simplifications.
For some applications, I manipulate trigonometric functions (spherical harmonics) and depending on the algorithm, the output formula could be very complicated.
However, in a lot of cases, trigonometric identities could help to simplify drastically the expressions.
For example, as pointed in this issue: https://github.com/grame-cncm/faust/issues/56, the algorithm outputs a matrix where all terms are functions which can be simplified in the majority of the cases. However, the output terms are not given in their simplest form, so far. For example, the term
rot(2,1,1)
in the algorithm described in the aforementioned issue gives:Which, after factorization gives
rot(2,1,1) = cos(roll)*cos(yaw)*(cos(pitch)^2 - sin(pitch)^2)) + sin(pitch)*sin(roll)*sin(yaw)
This latter expression is the output proposed by the compiler.However, knowing that
cos(pitch)^2 - sin(pitch)^2 = cos(2*pitch)
the previous expression could be simplified with:rot(2,1,1) = cos(roll)*cos(yaw)*cos(2*pitch) + sin(pitch)*sin(roll)*sin(yaw)
which is a simpler expression.Following this example, I'm wondering if it is possible for the compiler to recognize trigonometric identities, typically as given in the following link: http://artemath.com/artemath/cours/documents/docs/formulaire-trigo.pdf
Thank you ! Pierre