Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Suppose I have function f:

f[x_, y_] := 50000 + x 30000 + y 35000;

Now I want to find the x and y when f[]<=200000. I use Reduce:

Reduce[f[x, y] <= 200000 && 1 <= x <= 8 && 1 <= y <= 8 , {x,y}, Integers]

The result is:

(x == 1 && y == 1) || (x == 1 && y == 2) || (x == 1 && y == 3) || 
(x == 2 && y == 1) || (x == 2 && y == 2) || (x == 3 && y == 1)

Now I would like to use these results back into f[] but it requires formatting. I use:

results = Reduce[f[x, y] <= 200000 && 1 <= x <= 8 && 1 <= y <= 8, 
           {x, y},Integers] /. 
             Or[a__, b__] -> {a, b} /. 
              And[a_ == c_, b_ == d_] -> {c, d}

And I use:

f[#[[1]], #[[2]]] & /@ results

to get:

{115000, 150000, 185000, 145000, 180000, 175000}

I wonder if this is the right way to do this or if it can be done easier. It seems reduce can generate different (depending on the equations of course) formats of the results and this would mean that for every type of result new rules will be needed. Is this a fact of life?

share|improve this question
    
@rcollyer Thanks for editing. Still kind of struggling to get it nice.. –  Lou Feb 15 '12 at 20:20

3 Answers 3

up vote 19 down vote accepted

You may want to look at the documentation for ToRules. When applied to the output of Reduce you provided, the result is

Sequence[{x -> 1, y -> 1}, {x -> 1, y -> 2}, {x -> 1, y -> 3}, 
         {x -> 2, y -> 1}, {x -> 2, y -> 2}, {x -> 3, y -> 1}]

If you want to substitute this back to f[x,y], put curly braces to turn the sequence into a list and use ReplaceAll:

f[x,y] /. {%}

This will give the desired output {115000, 150000, 185000, 145000, 180000, 175000}.

share|improve this answer
    
+1, I was looking for ToRules and couldn't remember it. –  rcollyer Feb 15 '12 at 20:45
    
@rcollyer Thanks for editing my answer. I was so excited that I could finally contribute something that it did not occur to me to provide links or use the code block. –  Michael Wijaya Feb 15 '12 at 20:57
    
Not a problem. It was a nice answer. –  rcollyer Feb 15 '12 at 21:10

I'd do the following:

res = Reduce[f[x, y] <= 200000 && 1 <= x <= 8 && 1 <= y <= 8, {x, y}, Integers];
vals = Apply[List, res[[All, All, 2]], {0, 1}]
(*
==> {{1, 1}, {1, 2}, {1, 3}, {2, 1}, {2, 2}, {3, 1}}
*)

which uses Part in the form res[[All,All,2]] to get only the numerical values, and then Apply to replace the Or and And in the logical construct with List. For the second part, I'd again use Apply in its second short form:

f @@@ vals
share|improve this answer
50000 + x*30000 + y*35000 /. FindInstance[50000 + x*30000 + y*35000 < 200000 && 
    ((x == 1 && y == 1) || (x == 1 && y == 2) || (x == 1 && y == 3) || 
     (x == 2 && y == 1) || (x == 2 && y == 2) || (x == 3 && y == 1)), {x, y}, 
   Integers, 6]

(* ==>

{115000, 150000, 185000, 145000, 180000, 175000}

*)

share|improve this answer
    
What about when there are more results? It seems that I first need to know how many results there are. I mean the number 6 at the end. Is it better to use FindInstance for these type of equations? –  Lou Feb 15 '12 at 20:35
    
You can put 137 or whatever instead of 6. The documentation says: FindInstance[expr,vars,dom,n] will return a shorter list if the total number of instances is less than n. Whether FindInstance is better: I do not know. –  Rolf Mertig Feb 16 '12 at 9:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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