# How do I localize changes to a variable inside a Do-loop?

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

• This is not possible. Either pre-generate the t values and use Do[..., {t, tvals}] or use While. – Szabolcs Nov 10 '18 at 9:19
• @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 . – revanth roy Nov 10 '18 at 9:22
• Well, your example would quit after the first iteration if h could be changed. Can you show a realistic example? – Szabolcs Nov 10 '18 at 10:00
• @Szabolcs. It is perfectly possible and actually easy since an iteration variable isn't needed by the computation described. – m_goldberg Nov 12 '18 at 14:46
• @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. – Szabolcs Nov 12 '18 at 16:01

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.

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]]


h


0.1

Note how much the Do expression can be simplified.