1
$\begingroup$

How should I specify a discrete range for a parameter as one of the conditions in FindInstance? MemberQ/Element functions don't seem to work.

For example,

FindInstance[{x^2 + y^2 < 10, MemberQ[{1, 2, 5, 10}, x], MemberQ[{1/8, 1/4, 1/2, 1}, y]}, {x, y}]
FindInstance[{x^2 + y^2 < 10, x ∈ {1, 2, 5, 10}, y ∈ {1/8, 1/4, 1/2, 1} }, {x, y}] 
$\endgroup$
  • 1
    $\begingroup$ You can't. Please read the documentation of FindInstance[]. For small lists like your example, use Table[] and Select[] instead. $\endgroup$ – Somos May 21 at 2:30
1
$\begingroup$

You can use region objects for this purpose:

xvalues = {1, 2, 5, 10};
yvalues = {1/8, 1/4, 1/2, 1};

FindInstance[
    {
    x^2+y^2 < 10,
    {x} ∈ Point[List/@xvalues],
    {y} ∈ Point[List/@yvalues]
    },
    {x,y},
    10
]

{{x -> 1, y -> 1/8}, {x -> 1, y -> 1/4}, {x -> 1, y -> 1/2}, {x -> 1, y -> 1}, {x -> 2, y -> 1/8}, {x -> 2, y -> 1/4}, {x -> 2, y -> 1/2}, {x -> 2, y -> 1}}

Another possibility:

FindInstance[
    pt ∈ RegionIntersection[{
        Disk[{0, 0}, Sqrt[10]],
        RegionProduct[Point[List/@xvalues], Point[List/@yvalues]]
    }],
    pt,
    10
]

{{pt -> {1, 1/8}}, {pt -> {1, 1/4}}, {pt -> {1, 1/2}}, {pt -> {1, 1}}, {pt -> {2, 1/8}}, {pt -> {2, 1/4}}, {pt -> {2, 1/2}}, {pt -> {2, 1}}}

The problem with using MemberQ is that it always evaluates to True/False, while Element expects a domain specification or a region.

$\endgroup$
0
$\begingroup$
xvalues = {1, 2, 5, 10};

yvalues = {1/8, 1/4, 1/2, 1};

FindInstance[
 x^2 + y^2 < 10 && Or @@ Thread[x == xvalues] && 
  Or @@ Thread[y == yvalues], {x, y}, 8]

(* {{x -> 1, y -> 1/8}, {x -> 1, y -> 1/4}, {x -> 1, y -> 1/2}, 
    {x -> 1, y -> 1}, {x -> 2, y -> 1/8}, {x -> 2, y -> 1/4}, 
    {x -> 2, y -> 1/2}, {x -> 2, y -> 1}} *)

EDIT: Based on comparative timings, FindInstance is not the preferred approach.

$HistoryLength = 0;

hanlon = FindInstance[
    x^2 + y^2 < 10 && Or @@ Thread[x == xvalues] &&
     Or @@ Thread[y == yvalues], {x, y}, 8] //
   AbsoluteTiming;

woll = FindInstance[
    {x^2 + y^2 < 10,
     {x} ∈ Point[List /@ xvalues],
     {y} ∈ Point[List /@ yvalues]},
    {x, y}, 8] //
   AbsoluteTiming;

outer = Outer[
     If[#1^2 + #2^2 < 10, {x -> #1, y -> #2}, Nothing] &,
     xvalues, yvalues] //
    Flatten[#, 1] & //
   AbsoluteTiming;

The results are identical

Equal @@ Last /@ {hanlon, woll, outer}

(* True *)

However, using Outer is 300 times faster

(First /@ {hanlon, woll, outer})/outer[[1]]

(* {333.446, 308.769, 1.} *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.