0
$\begingroup$

I am struggling with using a While loop inside a Do loop and using the break to break the loop. In this code, I would like to use the While loop for the value of i and the Do loop for the value of h, I am defining what f is, and I am trying to change the value for i start with h=5 with the While loop, if the value of i gives out false for f, then I would like the loop to move on to evaluate f for the next values of h.

First I tried to define my inequality with specific h value (h=5);

f = Reduce[FunctionExpand[Binomial[n - 1, 5 - 1] + 2 - 2*\!\( \*UnderoverscriptBox[\(\[Sum]\), \(l = 0\), \(5 - 2\)]\(Binomial[ n - m, l]*Binomial[m - 1, 5 - l - 1]\)\)] <= 0 && m >= 5 + 1 && n >= (i/10)*5*m, {m, n}, Reals]

Then, I used Do loop to determine which value of i does not have solution. This is good, however, I would like to use the While loop instead of Do loop, I tried but it did not work. I am very new with loop in mathematica.

Do[Print[f], {i, 12, 14}]

With this, the output tells me that there is a solution when i=12, and false for 13 and 14. What I want is the first i value that gives me false. Now, Instead of me giving the range, I would like to make the loop start with certain value of i and stop when it first become false. After this, I would like to make the f more general by defining it as ;

f = Reduce[FunctionExpand[Binomial[n - 1, h- 1] + 2 - 2*\!\( \*UnderoverscriptBox[\(\[Sum]\), \(l = 0\), \(h - 2\)]\(Binomial[ n - m, l]*Binomial[m - 1, h - l - 1]\)\)] <= 0 && m >= h + 1 && n >= (i/10)*h*m, {m, n}, Reals]

And, use first loop to find the value for i, and then after it first gives false, then break and move to the next loop to evaluate the value of i for the next value of h.

This is what I tried;

Do[i = 12; While[f == true; If[false, Break[]]]; i++,{h,5,7}]

But the mathematica do not evaluate it.

I am sorry for the long explanation. However, I would really appreciate it if someone could give me any direction with the while loop and the break. Thank you so much.

Edit: I found the loop that I needed.Thank you.

$\endgroup$
5
  • $\begingroup$ What happens if you capitalize true and false? And exactly what is the value of f when you try that last line of code? $\endgroup$
    – Bill
    Feb 24, 2022 at 4:25
  • $\begingroup$ When I plugged in a specific value for h in f say h=5, the reduce give me a long solution, and when I did the Do loop, with {i,12,14}, for i=12, it gives me some values for m and n, but for i=13,14 it said False, False. But, when I redefine the f with the general value of h, it gives me a syntax error Reduce::nsmet: This system cannot be solved with the methods available to Reduce. $\endgroup$
    – Iras
    Feb 24, 2022 at 4:49
  • $\begingroup$ (continue from my previous comment since it was too long) and when I did the Do loop like the last code (I capitalize True and False this time) it gave me syntax error Reduce::fexp: Warning: Reduce used FunctionExpand to transform the system. Since FunctionExpand transformation rules are only generically correct, the solution set might have been altered. and General::stop: Further output of Reduce::fexp will be suppressed during this calculation. $\endgroup$
    – Iras
    Feb 24, 2022 at 4:50
  • $\begingroup$ Compare Do[i=12; Print["i is ",i]; i++,{h,5,7}] and i=12;Do[Print["i is ",i]; i++,{h,5,7}] $\endgroup$
    – Bill
    Feb 24, 2022 at 5:35
  • $\begingroup$ @Iras if I understand correctly what you want to do, you want to write a Do while loop in Mathematica, and I think that the answers here are very relevant mathematica.stackexchange.com/questions/99442/… $\endgroup$
    – kcr
    Feb 24, 2022 at 5:43

2 Answers 2

0
$\begingroup$

Defining f with SetDelayed (:=) gets it working.

f := Reduce[...]

Do[i = 12; While[i <= 14, Print[{h, i, f}]; i++], {h, 5, 7}]

Alternative loop

results = {};
Do[i = 12; While[i <= 14, f2 = f;
  If[f2 =!= False,
   AppendTo[results, {h, i, f2}]]; i++], {h, 5, 7}]
results
$\endgroup$
1
  • $\begingroup$ I appreciate the answer! I finally found the loop that I need. $\endgroup$
    – Iras
    Mar 29, 2022 at 3:15
0
$\begingroup$

I'll describe one strategy. I'm replacing your f with something simpler (Divisible) for now. Your basic approach of creating a loop and the breaking out is fine (especially if your search space is very large). The key question is how to capture your "positive" results. You an do this with Sow and Reap.

Reap[
  Do[
    Do[
      If[Divisible[j, i], Sow[{i, j}]; Break[]],
      {i, 2, 5}],
    {j, 10, 15}]]
(* returns {Null, {{{2, 10}, {2, 12}, {2, 14}, {3, 15}}}}*)

Do can actually take two iterators, but since Break will break out of the enclosing Do, we need to nest two Do expressions.

In your question, you said that Mathematica didn't evaluate your Do expression. This isn't true. It's just the case that Do isn't designed to return a value--it doesn't build a structure. Do just evaluates the body repeatedly. That's why you see examples of Do inluding a Print somewhere. Using Do implies that you're going to rely on side-effects.

What I would do next is to make your f expression into more of a "function" so that you can replace this

If[Divisible[j, i], Sow[{i, j}]; Break[]]

with something like this

If[f[i, j], Sow[{i, j}]; Break[]]
(*or maybe you want Not[f[i,j]]*)

It's not super critical, but it helps manage the scopes of variables (as well as just making things easier to understand).

$\endgroup$
1
  • $\begingroup$ I appreciate the answer! I have finally found the loop that I need. $\endgroup$
    – Iras
    Mar 29, 2022 at 3:15

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.