1
$\begingroup$

I want to change the increment value inside the do loop . But i dont know why it remains for the first declared value?

h = 0.1; x = 1.0;
Do[
 x = x + h;
 h++;
 Print[h];
 , {t, 0.0, 1.0, h}]

1.1

2.1

3.1

4.1

5.1

6.1

7.1

8.1

9.1

10.1

11.1

I actually want to change the value of increment (h) inside using do loop only.Can anyone help me to fix this

$\endgroup$
  • 3
    $\begingroup$ This is not possible. Either pre-generate the t values and use Do[..., {t, tvals}] or use While. $\endgroup$ – Szabolcs Nov 10 '18 at 9:19
  • $\begingroup$ @Szabolcs thanks for the reply can you post your idea with " Do" loop . I have tried with "While" but the program is too slow when i run for many iterations . $\endgroup$ – revanth roy Nov 10 '18 at 9:22
  • $\begingroup$ Well, your example would quit after the first iteration if h could be changed. Can you show a realistic example? $\endgroup$ – Szabolcs Nov 10 '18 at 10:00
  • $\begingroup$ @Szabolcs. It is perfectly possible and actually easy since an iteration variable isn't needed by the computation described. $\endgroup$ – m_goldberg Nov 12 '18 at 14:46
  • $\begingroup$ @m_goldberg I think we read the questions differently. I thought that OP had a starting value for the iterator and an ending value, but the iterator was incremented in a special, non-uniform way. In your solution, you fixed the number of iterations in advance at 11. I interpreted the question as wanting to stop when t reaches 1.0 (or some other threshold). Determining how many iterations this takes is not trivial in general. However, given that h becomes larger than 1 already in the 2nd step, and that t's upper bound is 1.0, the example shown by the OP does not make any sense to me. $\endgroup$ – Szabolcs Nov 12 '18 at 16:01
2
$\begingroup$

This is the rare occasion where For can do something that Do cannot do right from the start: Messing around with its iterator.

This is the way to do it with For:

tmax = 100000.;
hinc = 1.;
{x0, t0, h0} = {1.0, 0., 0.1};

Module[{x, t, h},
  For[x = x0; t = t0; h = h0;, t <= tmax,
   t += h;
   x += h;
   h += hinc
   ];
  x
  ] // AbsoluteTiming

{0.00173, 1.00055*10^6}

The variant with while could look like this:

Module[{x, t, h},
  x = x0; t = t0; h = h0;
  While[t <= tmax,
   x += h;
   t += h;
   h += hinc;
   ];
  x
  ] // AbsoluteTiming

{0.001732, 1.00055*10^6}

I thought about suffesting NestWhile but that one is a bit slower

First@NestWhile[
   {#[[1]] + #[[3]], #[[2]] + #[[3]], #[[3]] + hinc} &,
   {x0, t0, h0},
   #[[2]] <= tmax &
   ] // AbsoluteTiming

{0.004578, 1.00055*10^6}

In view of how complicated it is to set up, even if it has scoping built-in, I would not suggest it.

$\endgroup$
1
$\begingroup$

You can localize h within the Do-loop with Module which will keep the global h unchanged. Like so.

h = 0.1;
x = 1.0;
Module[{h = h},
  Do[x += h++; Print[Row[{x, "   ", h}]], 11]]

print

h

0.1

Note how much the Do expression can be simplified.

$\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.