What makes Rational.variables?


#1

I want to understand what a function Rational.variables does.
For example:

let printHS x = 
    x
    |> Seq.map(Infix.format)
    |> Seq.iter(printfn "    %s")

[|
    "(3/x^2 + 5*x)*(2*x+7)/(3*y-5) + 6*x/(4*y)"
    "(3/x^2 + 5*x)*(2*x+7)/(3*y-5)"
|]
|> Array.map(Infix.parseOrUndefined >> Rational.variables)
|> Array.iteri(fun i x -> printfn "\n%i:" i; x |> printHS)

Print:

0:
    x
    1/y
    7 + 2*x
    3/x^2 + 5*x
    1/(-5 + 3*y)

1:
    7 + 2*x
    3/x^2 + 5*x
    y

How to get these results?


(Christoph Rüegg) #2

This function interprets the provided expression as general rational expression, i.e. a fraction of two multivariate polynomials, and returns the set of generalized variables required for this interpretation. It does not apply any expansion during this process; would you expand it first using Rational.expand, variables would return the simple variables x and y for both expressions.

For example, (2*x + 3*y)/(z + 4) is a fully expanded simple rational expression, so Rational.variables would return x, y and z. Rational.expand would not have any effect.

On the other hand, 1/x + 1/y is only a rational expression if you interpret it as (a + b)/1 where a:=1/x and b:=1/y, hence Rational.variables returns the two generalized variables 1/x and 1/y. Rational.expand would transform it into (x + y)/(x*y), which is an equivalent simple rational expression.

Let’s have a look at your second expression, (3/x^2 + 5*x)*(2*x+7)/(3*y-5). The polynomial in the denominator is fully expanded, but the numerator is essentially a product of two expressions. This can therefore be interpreted as a multivariate rational expression only as (a*b)/(3*c-5), where a:=3/x^2 + 5*x, b:=2*x+7 and c:=y. And indeed, this is exactly what is returned by Rational.variables

The first expression (3/x^2 + 5*x)*(2*x+7)/(3*y-5) + 6*x/(4*y) as is does not have a denominator except 1, so the whole expression has to be interpreted as the multivariate polynomial numerator. Note that a division a/b can be considered as product a*(1/b). This way, we can rewrite the expression (again without applying any expansion) as (3/x^2 + 5*x) * (2*x + 7) * 1/(3*y-5) + 6/4 * x * 1/y. And therefore Rational.variables returns exactly these variable terms as generalized variables, as you printed in the question.

Does that make any sense?


#3

Great, thank you. Now everything fell into place.