Skip to main content
3 of 4
added 239 characters in body
theorist
  • 3.7k
  • 1
  • 16
  • 31

Way to assign restrictions to rational solutions from Solve/Reduce/FindInstance?

I want to restrict the outputs of Solve/Reduce/FindInstance, etc. to "simple" rationals, which I define as rationals of the form:

$\pm \dfrac{a}{b}$, where a, b = {1, 2, 3, 4, 5, 6}

e.g., $ \dfrac{3}{5}$, $5$, $- \dfrac{4}{3}$, etc

Since MMA associates the sign with the numerator, e.g.:

g = -3/4; Numerator@g Denominator@g 

-3

4

...I believe restrictions on rationals can be represented as follows:

g = -3/4; h = 5; -6 <= Numerator@g <= 6 && 1 <= Denominator@g <= 6 0 <= Numerator@g <= 6 && 1 <= Denominator@g <= 6 0 <= Numerator@h <= 6 && Denominator@h == 1 -6 <= Numerator@h <= 6 && 2 <= Denominator@h <= 6 

True

False

True

False

However, Solve, Reduce, and FindInstance don't recognize this.

For example:

exprA = p + \[Rho] + \[Sigma] == 0 && -p + r + 2 \[Nu] - 3 \[Rho] == 0 && -2 p - \[Nu] - 2 \[Sigma] == 1 

enter image description here

FindInstance[ exprA && -6 <= Numerator@\[Sigma] <= 6 && 1 <= Denominator@\[Sigma] <= 6 && -6 <= Numerator@\[Nu] <= 6 && 1 <= Denominator@\[Nu] <= 6 && -6 <= Numerator@r <= 6 && 1 <= Denominator@r <= 6 && -6 <= Numerator@p <= 6 && 1 <= Denominator@p <= 6 && -6 <= Numerator@\[Rho] <= 6 && 1 <= Denominator@\[Rho] <= 6, {\[Sigma], \[Nu], r, p, \[Rho]}, Rationals, 2] 

enter image description here

With fewer variables (say, 3 instead of 5), I could instead brute-force the restriction by explicitly reformatting each variable as the ratio of sub-variables, applying value and domain restrictions to each—e.g., replacing the variable $r$ with $\frac{r1}{r2}$, where $-6 <= r1 <= 6$, $1 <= r2<= 6$, $r1\in \mathbb{Z}$ and $r2\in \mathbb{Z}$. One can then use Table or Map to recombine the sub-variables in the output into rational solutions for the variables, and delete the duplicates. E.g.:

exprB = -((3 r1)/r2) - \[Nu]1/\[Nu]2 + \[Sigma]1/\[Sigma]2 == 0 && r1/r2 + \[Nu]1/\[Nu]2 == 0 && -((2 \[Nu]1)/\[Nu]2) == 1 

enter image description here

soln = Solve[ exprB && {\[Sigma]1, \[Sigma]2, \[Nu]1, \[Nu]2, r1, r2} \[Element] Integers && And @@ Thread[-6 <= {\[Sigma]1, \[Sigma]2, \[Nu]1, \[Nu]2, r1, r2} <= 6], {\[Sigma]1, \[Sigma]2, \[Nu]1, \[Nu]2, r1, r2}]; tab = DeleteDuplicates@ Table[soln[[j, i, 2]]/soln[[j, i + 1, 2]], {j, 1, Length@soln}, {i, 1, Length@soln[[1]] - 1, 2}]; TableForm[tab, TableHeadings -> {None, {"\[Sigma]", "\[Nu]", "r"}}] 

enter image description here

However, this method doesn't work with exprA, since its five variables become 10, making the calculation take too long. [I stopped the following after it ran for 24 hours on my 2019 i9 iMac without producing a result.] Thus it would be nice if there were a way to apply the restrictions directly to the original rational-valued variables, rather than transforming them to ratios of integer-valued variables and thus doubling their number:

exprC = exprA/. {\[Sigma] -> (\[Sigma]1/\[Sigma]2), \[Nu] -> (\[Nu]1/\[Nu]2), r -> (r1/r2), p -> (p1/p2), \[Rho] -> (\[Rho]1/\[Rho]2)} 

enter image description here

soln = Solve[ exprC && And @@ Thread[-6 <= {\[Sigma]1, \[Sigma]2, \[Nu]1, \[Nu]2, r1, r2, p1, p2, \[Rho]1, \[Rho]2} <= 6] && {\[Sigma]1, \[Sigma]2, \[Nu]1, \[Nu]2, r1, r2, p1, p2, \[Rho]1, \[Rho]2} \[Element] Integers, {\[Sigma]1, \[Sigma]2, \[Nu]1, \[Nu]2, r1, r2, p1, p2, \[Rho]1, \[Rho]2}] tab = DeleteDuplicates@ Table[soln[[j, i, 2]]/soln[[j, i + 1, 2]], {j, 1, Length@soln}, {i, 1, Length@soln[[1]] - 1, 2}]; TableForm[tab, TableHeadings -> {None, {"\[Sigma]", "\[Nu]", "r", "p", "\[Rho]"}}] 
theorist
  • 3.7k
  • 1
  • 16
  • 31