# 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.