I am sure this is the right site for this question, but feel free to move it to another stackexchange site if it works better.
Suppose you have the sum of fractions a1/d1 + a2/d2 + … + an/dn . You want to calculate the total numerator and denominator, i.e. Rewrite it as p/q . We have the formula
p = a1*d2*…*dn + d1*a2*d3*…*dn + … + d1*d2*…d(n-1)*an q = d1*d2*…*dn.
What is the most efficient way to calculate these things, in particular p ? You can see that if you calculate it naively, that is, using the formula above, you calculate a lot of redundant things. For example, you will calculate d1*d2 n-1 times.
My first thought was to iteratively compute d1*d2 , d1*d2*d3 , ... and dn*d(n-1) , dn*d(n-1)*d(n-2) ,. .. but even this is inefficient because you end up calculating the “average” multiplications twice (for example, if n is big enough, you double calculate d3*d4 ).
I am sure that this problem can be expressed in some way, using, perhaps, some kind of graph theory or combinatorics, but I have not studied this material enough to reflect on this well.
And one note: I'm not interested in cancellation, just the most efficient way to propagate things.
UPDATE:
I should have known that people on stackoverflow assume that these are numbers, but I'm so used to my use case that I forgot to mention it.
We cannot simply "divide" an into each member. The use case here is a symbolic system. In fact, I'm trying to fix a function called .as_numer_denom() in the SymPy computer algebra system , which currently calculates this naively. See the related SymPy issue .
Separation of things has some problems that I would like to avoid. Firstly, there is no guarantee that everything will be canceled. This is due to the fact that mathematically (a*b)**n != a**n*b**n in the general case (if a and b are positive, then, for example, if a == b ==-1 and n == 1/2 , you get (a*b)**n == 1**(1/2) == 1 , but (-1)**(1/2)*(-1)**(1/2) == I*I == -1 ). Therefore, I don’t think it’s good to assume that dividing by an will cancel it in the expression (this may be practically unreasonable, I will need to check what the code does).
Secondly, I would also apply this algorithm to calculate the sum of rational functions. In this case, the members will automatically be multiplied together by one polynomial, and the "division" of each of an will include the application of the polynomial division algorithm. You can see in this case, you really want to calculate the most effective multiplication in the first place.
UPDATE 2:
I think that my concerns about the abolition of symbolic terms may be unfounded. SymPy does not override features like x**n*x**(m - n) automatically, but I think that any metrics that will be combined through multiplication will also be combined through division, so the credentials should be revoked.
There is a problem with constants that automatically distribute all additions, for example:
In [13]: 2*(x + y)*z*(S(1)/2) Out[13]: z⋅(2⋅x + 2⋅y) ───────────── 2
But this is the first mistake and the second can never be a problem (I think), because 1/2 will be divided into 1 and 2 according to the algorithm, which receives the numerator and denominator of each term.
However , I still want to know how to do this without “dividing” di from each term, so that I can have an efficient algorithm for summing rational functions.