11

Say I want to do the following:

Reduce[ x+y+z==1, {x,y,z}, Modulus -> 7 ]

then I get a solution with parameters, C[1] :

x == 1 + 6 C[1] + 6 C[2] && y == C[2] && z == C[1]

Now, for non-linear equations, such as

Reduce[x + y^2 + z == 1, {x, y, z}, Modulus -> 7]

I get a complete list of solutions, here are the first 5 of them :

%[[ ;; 5]]
(x == 0 && y == 0 && z == 1) || (x == 0 && y == 1 && z == 0) || 
(x == 0 && y == 2 && z == 4) || (x == 0 && y == 3 && z == 6) ||
(x == 0 && y == 4 && z == 6)

Is there a way to make the system yield this type of output also in the first case ? (Of course, I can just loop over all possibilities of the parameter and get a complete list, but I'd prefer to make Mathematica do it for me if it is possible.)

Artes
  • 57,212
  • 12
  • 157
  • 245
Per Alexandersson
  • 2,469
  • 15
  • 19

3 Answers3

13

This tutorial Diophantine Polynomial Systems collects useful methods for tackling similar problems. There one finds e.g. :

Mathematica enumerates the solutions explicitly only if the number of integer solutions of the system does not exceed the maximum of the $p^{th}$ power of the value of the system option DiscreteSolutionBound, where p is the dimension of the solution lattice of the equations...

That is a necessary but not sufficient condition. Increasing DiscreteSolutionBound (by default 10) doesn't help here e.g.

SetSystemOptions["ReduceOptions" -> "DiscreteSolutionBound" -> 1000];

On the other hand there are instances of limitations of Reduce when we work with the Modulus option (see e.g. : Solving/Reducing equations in Z/pZ) and most likely this is the case here.

Nonetheless one can make Reduce write all solutions explicitly. A straightforward way is to substitute all generated parameters (since they are protected) by another symbols, and using Table to write all cases. Then we have to use Mod[#, 7]& since Reduce[..., Modulus->7] is inside Table.

Flatten[
  Mod[ Table[{x, y, z} /.ToRules[ 
         Reduce[ x + y + z == 1, {x, y, z}, Modulus -> 7] ] /. {C[1] -> a, C[2] -> b},
         {a, 0, 6}, {b, 0, 6}],  7],  1]
{{1, 0, 0}, {0, 1, 0}, {6, 2, 0}, {5, 3, 0}, {4, 4, 0}, {3, 5, 0}, {2, 6, 0},
 {0, 0, 1}, {6, 1, 1}, {5, 2, 1}, {4, 3, 1}, {3, 4, 1}, {2, 5, 1}, {1, 6, 1}, 
 {6, 0, 2}, {5, 1, 2}, {4, 2, 2}, {3, 3, 2}, {2, 4, 2}, {1, 5, 2}, {0, 6, 2}, 
 {5, 0, 3}, {4, 1, 3}, {3, 2, 3}, {2, 3, 3}, {1, 4, 3}, {0, 5, 3}, {6, 6, 3}, 
 {4, 0, 4}, {3, 1, 4}, {2, 2, 4}, {1, 3, 4}, {0, 4, 4}, {6, 5, 4}, {5, 6, 4}, 
 {3, 0, 5}, {2, 1, 5}, {1, 2, 5}, {0, 3, 5}, {6, 4, 5}, {5, 5, 5}, {4, 6, 5}, 
 {2, 0, 6}, {1, 1, 6}, {0, 2, 6}, {6, 3, 6}, {5, 4, 6}, {4, 5, 6}, {3, 6, 6}}

or we can use the Mod function more extensively in the integers with appropriate bounds on the variables x, y, z e.g.

Mod[{x, y, z} /. {ToRules[ Reduce[x + y + z == 1 && -10 < x < 10 &&
                                  -10 < y < 10 && -10 < z < 10, {x, y, z}, Integers]]
                 }, 7] // DeleteDuplicates

Reduce is recommended when we have non-linear equations. In a special case of linear equations namely the Frobenius equations $\; a_1 x_1 +\dots + a_n x_n =b \quad$ (where $a_i$ - positive integers, $x_i$ - nonnegative integers and $b$ is an integer) instead of working with Reduce in the integers we can use FrobeniusSolve for a much more efficient approach (see e.g. Finding the number of solutions to a diophantine equation) :

Flatten[ Mod[ Table[ FrobeniusSolve[ {1, 1, 1}, 1 + 7 k], {k, 2}], 7], 1]//
DeleteDuplicates

All these methods yield identical results with respect to the ordering.

Artes
  • 57,212
  • 12
  • 157
  • 245
4

Making it a non-linear equation works :)

Reduce[(x + y + z - 1)^2 == 0, {x, y, z}, Modulus -> 7]

$$ (x=0\land y=0\land z=1)\lor (x=0\land y=1\land z=0)\lor (x=0\land y=2\land z=6)\lor (x=0\land y=3\land z=5)\lor (x=0\land y=4\land z=4)\lor (x=0\land y=5\land z=3)\lor (x=0\land y=6\land z=2)\lor (x=1\land y=0\land z=0)\lor (x=1\land y=1\land z=6)\lor (x=1\land y=2\land z=5)\lor (x=1\land y=3\land z=4)\lor (x=1\land y=4\land z=3)\lor (x=1\land y=5\land z=2)\lor (x=1\land y=6\land z=1)\lor (x=2\land y=0\land z=6)\lor (x=2\land y=1\land z=5)\lor (x=2\land y=2\land z=4)\lor (x=2\land y=3\land z=3)\lor (x=2\land y=4\land z=2)\lor (x=2\land y=5\land z=1)\lor (x=2\land y=6\land z=0)\lor (x=3\land y=0\land z=5)\lor (x=3\land y=1\land z=4)\lor (x=3\land y=2\land z=3)\lor (x=3\land y=3\land z=2)\lor (x=3\land y=4\land z=1)\lor (x=3\land y=5\land z=0)\lor (x=3\land y=6\land z=6)\lor (x=4\land y=0\land z=4)\lor (x=4\land y=1\land z=3)\lor (x=4\land y=2\land z=2)\lor (x=4\land y=3\land z=1)\lor (x=4\land y=4\land z=0)\lor (x=4\land y=5\land z=6)\lor (x=4\land y=6\land z=5)\lor (x=5\land y=0\land z=3)\lor (x=5\land y=1\land z=2)\lor (x=5\land y=2\land z=1)\lor (x=5\land y=3\land z=0)\lor (x=5\land y=4\land z=6)\lor (x=5\land y=5\land z=5)\lor (x=5\land y=6\land z=4)\lor (x=6\land y=0\land z=2)\lor (x=6\land y=1\land z=1)\lor (x=6\land y=2\land z=0)\lor (x=6\land y=3\land z=6)\lor (x=6\land y=4\land z=5)\lor (x=6\land y=5\land z=4)\lor (x=6\land y=6\land z=3) $$

Andrew
  • 2,513
  • 17
  • 15
  • Interesting (+1), have you got any justification of the issue ? – Artes May 13 '13 at 11:56
  • This will work for a prime modulus, but not for one under which there is a non-trivial square-root of 0 (e.g. Mod[6^2, 12] == 0). – Michael E2 May 13 '13 at 12:41
  • @Artes May be Mma explicitly checks for linearity, where it knows how to write parametrized solutions, and in non-linear case uses some other algorithms. – Andrew May 13 '13 at 16:21
  • @MichaelE2 It can be taken into account Reduce[Reduce[(x + y + z - 1)^2 == 0, {x, y, z}, Modulus -> 36], Modulus -> 6] – Andrew May 13 '13 at 16:38
3

Here's another way expand the solutions to a linear equation:

Evaluate@Reduce[x + y + z == 1, {x, y, z}, Modulus -> 7, 
    GeneratedParameters -> Slot] & @@@ Tuples[Range[0, 6], 2]

  (* {x == 1 && y == 0 && z == 0, x == 7 && y == 1 && z == 0, ...,
      x == 73 && y == 6 && z == 6} *)

There are two differences from the normal output of Reduce: the output is a list instead of a logical expression, and the values are not the least nonnegative residues modulo 7. One can process the output to suit one's needs: Apply Or, reduce each Integer with % /. n_Integer :> Mod[n, 7], convert to rules with ToRule /@ %, and so on.

Michael E2
  • 235,386
  • 17
  • 334
  • 747