1.6. Repeated Evaluation: While-Loops#
for
-loops are ideal when you know the number of iterations in advance, like when computing a finite sum \(s_n = \sum_{i=1}^n \frac{1}{i}\).
However, sometimes the number of iterations isn’t known beforehand. For example, what if we needed to add terms to \(s_n\) until the next term becomes smaller than some tolerance \(\delta\)? For problems like this, a while
-loop is the perfect tool.
The basic syntax is:
while condition
# This code will repeat as long as the condition is true
end
1.6.1. Key Points#
If the
condition
isfalse
initially, the loop body will never execute.If the
condition
never becomesfalse
, you will create an infinite loop.You typically need to initialize a variable before the loop that is used in the condition, and then update that variable inside the loop.
Here is how we can solve the problem from above: compute \(s_n\), stopping when a term is smaller than \(\delta\).
function compute_s_delta(δ)
s = 0.0
term = 1.0
i = 1
while term ≥ δ
s += term
i += 1
term = 1 / i
end
return s
end
compute_s_delta (generic function with 1 method)
compute_s_delta(0.1)
2.9289682539682538
compute_s_delta(1e-8)
18.997896413852555
1.6.2. The break
Statement#
Sometimes it is useful to exit a loop from somewhere in the middle of its body. The break
statement allows you to do this immediately.
while condition
# ... some code ...
if termination_condition
break
end
# ... more code ...
end
This pattern is very common. A popular technique is to create a deliberate infinite loop with while true
and then use an if
condition with break
to control the exit.
1.6.3. The continue
Statement#
The continue
statement is similar to break
, but instead of exiting the loop entirely, it immediately skips to the next iteration, bypassing any remaining code in the current iteration. This is useful for skipping certain steps under specific conditions.
1.6.4. Example: Square Root Calculation#
A classic way to compute square roots is with Newton’s method. To find \(\sqrt{a}\), we can iteratively improve an estimate \(x_n\) using the formula:
We start with an initial guess, like \(x_0 = 1.0\), and repeat until the change between successive estimates is smaller than some tolerance \(\varepsilon\). This is a perfect task for a while
-loop, and we will explore two common ways to structure it.
1.6.4.1. Method 1: Using while true
and an if
statement#
One popular and readable pattern is to create an infinite loop with while true
and then use an if
statement to exit once the convergence criterion is met. This keeps the termination logic cleanly separated inside the loop body.
While break
is often used to exit a loop, it’s even more direct to use return
when the loop is inside a function. This immediately exits the entire function and sends back the final value, making the code more concise.
function my_sqrt_v1(a, ε = 1e-15) # Use a default value for the tolerance ε
x = 1.0 # Initial guess
while true
println("Current estimate: x = ", x)
x_new = (x + a/x) / 2
# Check for convergence and exit the loop if met
if abs(x_new - x) < ε
return x_new # Return the final, converged value
end
x = x_new
end
end
my_sqrt_v1 (generic function with 2 methods)
my_sqrt_v1(256)
Current estimate: x = 1.0
Current estimate: x = 128.5
Current estimate: x = 65.24610894941634
Current estimate: x = 34.58485728656987
Current estimate: x = 20.993470372021676
Current estimate: x = 16.59386909154118
Current estimate: x = 16.010626831390027
Current estimate: x = 16.00000352670594
Current estimate: x = 16.00000000000039
Current estimate: x = 16.0
16.0
1.6.4.2. Method 2: Condition in the while
Statement#
A more traditional approach is to place the termination logic directly in the while
loop’s condition. This requires carefully initializing variables before the loop starts to ensure the condition can be evaluated correctly on the first pass.
function my_sqrt_v2(a, ε = 1e-15)
x = 1.0
x_new = (x + a/x) / 2 # Calculate the first step to initialize the change
# Loop as long as the change is greater than or equal to the tolerance
while abs(x_new - x) ≥ ε
println("Current estimate: x = ", x_new)
x = x_new
x_new = (x + a/x) / 2
end
return x_new
end
my_sqrt_v2 (generic function with 2 methods)
my_sqrt_v2(256)
Current estimate: x = 128.5
Current estimate: x = 65.24610894941634
Current estimate: x = 34.58485728656987
Current estimate: x = 20.993470372021676
Current estimate: x = 16.59386909154118
Current estimate: x = 16.010626831390027
Current estimate: x = 16.00000352670594
Current estimate: x = 16.00000000000039
Current estimate: x = 16.0
16.0