Simple Programs
3.4 Iterative Routines
Consider the quadratic equation
px2þ qx þ r ¼ 0
where p, q, and r are constants. The solutions can be directly obtained using the formula
x¼q ffiffiffiffiffiffiffiffiffiffiffiffiffiffiffiffiffi q2 4pr p
2p
If p = 1, q =−3, and r = 2, we get 1 and 2 as the possible solutions. There are a number of situations where a solution cannot be obtained directly in this manner.
A widely adopted procedure is to select an appropriate iterative method of solving such equations (Kreyszig2006). Let us illustrate this through an example.
Example 3.10 Find the cube root of 10.
It is implicitly assumed here that we do not have access to log tables or cal-culator based procedures which yield the cubic root directly. We fall back on a‘trial and error’ approach—a binary search. The procedure involves the following steps:
1. Let a = 10—a is assigned the value of the number whose cube root we seek.
2. Starting withb = 1, get b3 as b3.
3. Incrementb and get its cube. Do this successively until b3exceedsa.
4. Now we know that the cube root ofa lies between the last value of b and that of b − 1. Let b1 = b − 1 and b2 = b. This completes the first part of the iteration.
5. Compute bm—the mean of b1 and b2 as bm = (b1 + b2)/2.
6. Obtainbm3. Ifbm3 >a, we know that the cube root of a lies between b1 and bm. Assign bm to b2 as b2 = bm. Proceed to step 8.
7. Ifbm3≤ a in step 6, we know that the cube root of a lies between bm and b2.
Assignbm to b1 as b1 = bm.
8. If bm and b1 (or bm and b2) are sufficiently close, we take bm as the cube root value with the desired level of accuracy; else we go back to step 5.
9. The iterative procedure outlined above is depicted in flowchart form in Fig. 3.14. The Python code for the example is in Fig.3.15.—[1]–[6]. The result is in [7]. We have introduced a counter—‘n’—in the routine to keep track of the number of iterations gone through. If n exceeds a preset limit we terminate the program. Here the limit has been set as 20. When execution is completed we get the desired cube root of a as 2.1552734375; the solution is after 10 iterative cycles.
start
end Output bm
a = 10 b, b3, n = 1, 1, 0
Increment b b3< a yes
no
b1, b2 = b-1, b
yes b2-b1>0.001 no and n < 20 Increment n
bm = (b1+b2)/2
a > b3
b1 = bm no yes
b2 = bm
Fig. 3.14 Flowchart for Example3.10
32 3 Simple Programs
The routine also illustrates the use of keyword—‘else’. else is always used in combination with if to steer a routine through one or the other alternative code groups. The iteration process—reduction in the search range of solution in suc-cessive iteration cycles gone through is depicted in Fig.3.16. The following are noteworthy here:
• The approach followed is of a ‘divide and conquer’ type; with each successive step the search range is halved. In turn the % error or indecision in the value of the cube root obtained is also halved.
• Since 2−10 = 1/1024, the condition b1– b2 ≤ 0.001 (=1/1000) is achieved in 10 successive iterations. Hence n = 10 when the iteration stops.
• If ε denotes the accuracy specified (ε = 0.001 here), as ε reduces the number of iterative cycles required to achieve the specified accuracy increases. In fact the number of iterative cycles required isdlog2ee.
• Beyond a limit the cumulative effect of truncation errors will dominate, pre-venting further improvement in accuracy (error propagation is not of direct interest to us here).
• 2.15527343753 – 10 = 0.01168391. The fractional error in the cube value is 0.001168391 = 0.117%.
>>> a = 10 [1]
>>> b, b3, n = 1, 1, 0 [2]
>>> while b3 < a: [3]
... b +=1 ... b3 = b**3 ... >>> b1, b2 = b-1, b
>>> while (b2 - b1 > 0.001) and (n < 20): [4]
... n += 1
... bm = (b1 + b2)/2.0
... if a > bm**3:b1 = bm [5]
... else: b2 = bm [6]
...
>>> print('bm = ', bm, ', n = ', n, ',a = ', a)[7]
bm = 2.1552734375 , n = 10 ,a = 10
>>> b, b3, n = 1, 1, 0 [8]
>>> while b3 < a: [9]
... b +=1 ... b3 = b**3
... >>> b1, b2 = b-1, b [10]
>>> while (abs(b3-a)/a > 0.001) and (n < 20): [11]
... n += 1
... bm = (b1 + b2)/2.0
... if a > b3: b1 = bm [12]
... else: b2 = bm [13]
... >>> print('bm = ', bm, ', n = ', n, ',a = ', a) bm = 2.154296875 , n = 9 ,a = 10
Fig. 3.15 Python iterative sequence for Example3.10
• The program is run with the termination condition altered to that in [11] in Fig. 3.15. The accuracy for termination is specified in terms of the cube value (in contrast to the last case where it was in terms of the cube root value). The program stops after nine iterations. The cube root value obtained is 2.154296875. Correspondingly the fractional error is |(2.1542968753 – 10)|/
10 = 0.0001919.
As mentioned earlier the successive bifurcation procedure outlined here can be used to seek solution for a variety of equations. More often we seek solutions for x such that f(x) = 0 where f(x) is a specified function of x. For the above case
Iteration cycle Search range
2.0 3.0
2.0 2.5
1
2
2.0 2.25
3
2.125 2.25
4
2.125 2.1875
5
2.125 2.15625
6
2.1328125 2.15625 7
2.138671875 2.15625 8
2.1396484375 2.15625 9
Fig. 3.16 Narrowing of the search range in successive iterations for Example3.10
34 3 Simple Programs
f(x) = 10– x3. In all these cases we should have a clear prior idea of the possible range of solutions and the number of solutions in the range. This is to prevent a
‘wild-goose-chase’ situation.
The sequence in Fig.3.17 is a slightly altered approach to the problem in Example3.10. Here the search interval in every iterative cycle is reduced to 1/3rd of the preceding one—[1] and [4]. As in the preceding case starting with one, b is successively incremented until a value ofb whose cube exceeds a is identified. The desired cube root ofa lies between b − 1 and b. This base interval is divided into three equal intervals ([1] and [2])—ba to bb, bb to bc and bc to b itself. a is compared withba3,bb3, and bc3and the interval where it lies is identified. This forms the base interval for the start of the next iteration. It is again divided into three equal segments—[4]—(each of length 1/3rd of the previous case) and ba, bb, and bc reassigned to the respective new segment boundary values. The iterative cyclic process is continued until the interval is close enough to zero. The acceptable interval limit specified to stop iteration here [3] is 0.0001. The cube root value is obtained in eight iterations; its value is 2.154448000812884 2.1544480008128843 – 10 = 0.00018535 is the error in the cube value.
The example here also illustrates the use of keyword—elif (stands for ‘else if’)—[5]. The condition chain—if … elif…elif … elif…else … can be used judiciously to test multiple conditions and steer a routine to respective code segments.
The iteration termination has been specified here in terms of accuracy in the root value. If necessary it can be specified in terms of the same in the cube value as was done earlier in the approach using bifurcation of the intervals.
>>> while b3 < a:
... b +=1 ... b3 = b**3
... >>> d = 1/3 [1]
>>> ba, bb, bc, = b-1, b-2*d, b – d [2]
>>> bb3, bc3 = bb**3, bc**3
>>> while (bc-bb > 0.0001) and (n < 20): [3]
... n += 1
... d = (bc - bb)/3 [4]
... if a < bb3:
... bb, bc = ba+d, ba+2*d
... elif a < bc3: [5]
... ba, bb, bc = bb, bb+d, bb+2*d
... else: [6]
... ba, bb, bc = bc, bc+d, bc+2*d ... bb3, bc3 = bb**3, bc**3
...
>>> print('bb = ', bb, ', n = ', n, ',a = ', a) bb = 2.154448000812884 , n = 8 ,a = 10
Fig. 3.17 Python Interpreter sequence with the altered approach for Example3.10
3.5 Exercises
1. x¼ P6 i¼2j ji j
1=j
: Write a Python program to evaluate x for:
a. j = 1, 3, 10, 30, 100 b. j =−1, −3, −10, −30, −100 c. j = 1, 1/3, 1/10, 1/30, 1/100 d. j =−1, −1/3, −1/10, −1/30, −1/100
All the above represent norms of vectors infinite dimensional linear spaces (of dimension 5). The vector component values have been taken as 2, 3, 4, 5, and 6.
If j increases in the positive direction the larger magnitude gets more weight;
eventually as j tends to infinity only the largest magnitude prevails. As j de-creases from one, difference in contributions from components become less pronounced; in the limit as j tends to zero, all components are given equal weight. For negative values of j smaller magnitudes prevail over the larger ones with behavior characteristics as above. Choice of j helps to focus on selected characteristics of spaces
2. Write a Python program to evaluate the following iteratively. Continue the iteration until the change due to the last element as a fraction of the latest value is less than 10−6:
a. x¼ 1 þ11!þ21!þ31!þ41!. . .
b. fðxÞ ¼ 1 þ1x!þx22!þx32! þx44!. . . for x = −0.1, −0.3, +0.1, +1.0, +3.0, +10.0 c. fðxÞð¼ sin xÞ ¼1x!x33! þx55!x77!. . . for x = −0.1, −0.3, +0.1, +1.0, +3.0,
+10.0
d. fðxÞð¼ cos xÞ ¼ 1 x22! þx44!x66!þx88!. . . for x = −0.1, −0.3, +0.1, +1.0, +3.0, +10.0
3. Write a Python program to evaluate 5.17.2, 5.1−7.2, 5.11/7.1, 5.1−1/7.1. Use 5.17.2= 5.17*5.10.2. Compute 5.10.2iteratively and multiply it by 5.17. To get x−yevaluate xyand take its reciprocal.
4. Modify the program for Example 3.9as indicated below, run the same, and comment on the results:
a. Use break in place of continue.
b. Use the if… else combination.
c. Swap the odd and even segments and do the above.
5. Numerical methods of solving equations (even in a single variable) take various forms. Unless one has a fairly clear idea of the nature/region of the solution sought things may go haywire. As an example consider the solution of the quadratic in x: x2– x – 1 = 0. The two solutions are 0.5(1± ffiffiffi
p5
). One approach to solving for x is as follows:
36 3 Simple Programs
yðxÞ ¼ x þ 1 ð3:1Þ
yðxÞ ¼ x2 ð3:2Þ
Start with a value for x, substitute it in (3.1) to get y. Use this value of y in (3.2) and solve for next approximate value of x. Continue this iteratively until the difference in successive values of x is within the acceptable limit. If x does not converge within a specified number of iterations, give up! Write a program to solve the given equation for x. Start with x = 0 as initial value. Solution of (3.2) yields two values for x; proceed with both.
Write a program to solve for x starting with (3.2) and try it with initial value x = 0.
6. Consider the cubic equation y(x) = x3+ ax2+ bx + c = 0. Since y(0) = c, y(x) has a real root with a sign opposite that of c. If c is positive, one can evaluate y for different values of x (say −0.1, −1.0, −10.0, −100.0) until y is negative.
Then a negative root can be obtained following the algorithm in Example3.10.
If c is negative a similar procedure can be followed with positive values of x to extract a positive root. The remaining roots can be obtained by solving the remaining quadratic factor. Write a program to solve a cubic polynomial. Solve the cubic for the sets of values—(1.0, 1.0, 1.0), (1.0, 1.0, −1.0), (1.0, 10.0, 10.0), (1.0, 10.0,−10.0), and (1.0, −10.0, 10.0), of the set (a, b, c).
7. Newton-Raphson method: the method solves y(x) = o for x using afirst degree polynomial approximation of y as
y1¼ y0þdy dx
x0
dx
where y0is the value of y at x = x0. With y1= 0 we have dx ¼ y0
dy dx
x0
With x1= x0+δx evaluate next y. Continue iteratively until difference in successive values of x is within tolerance specified. Write a Python program for the general case (Make room for iteration failure with an upper limit to the number of iterations). Solve e−x– 2 cosx = 0 in the interval (0, π/2).
Apply the method to get the cube root of 10.
8. With (x1, y1) and (x2, y2) as two points on a straight line in the (x, y) plane, equation of the straight line through the two points is
y¼ y1þy2 y1
x2 x1ðx x1Þ ð3:3Þ
Solving this for y = 0 yields the solution x0. The procedure can be extended to solve y(x) = 0 for x.
Get two points (x1, y1) and (x2, y2) as on the curve with y1 and y2being of opposite signs. Form (3.3) and get x3. Evaluate y3by substituting in the given function. If y1and y3are of different signs, form the equation similar to (3.3) for next iteration using (x1, y1) and (x3, y3); else use (x2, y2) and (x3, y3) for it.
Continue the iteration until solution (or its failure!). Write a Python program for the iterative method. Solve the equations in Exercise (7) above.
9. An amount of c rupees is deposited every month in a recurring deposit scheme for a period of y years. Annual interest rate is p%. Write a program to get the accumulated amount at the end of the deposit period with compounding done at the end of every year. Write a program to get the accumulated amount if the compounding is done monthly. Get the accumulated amounts for c = 100, p = 8, and y = 10.
10. A bank advances an amount of d rupees to a customer at p% compound interest. He has to repay the loan in equated monthly installments (EMI) for y years. Write a program to compute the EMI (EMI based loan repayment is the reverse of the recurring deposit scheme). Get the EMI for d = 10, 000, p = 10, and y = 10.
11. Depreciation:
a. In‘straight line depreciation’ if an item (of machinery) is bought for p ru-pees and its useful life is y years the annual depreciation is p/y ruru-pees.
b. In‘double declining balance’ method if the annual depreciation is d%, the book value of the item at the end of y years is (1− (d/100))y times its bought out value. The annual reduction in book value is the depreciation.
c. In‘Sum of years digit’ method of depreciation, with y as the useful life in years of an item form s as the sum of integers up to (and including) y. The depreciation in the xth year is (x/s) times the bought out value.
Write programs to compute depreciation by all the three methods. With p = 80,000, y = 10, d = 10, get the depreciation and the book values at the end of each year forfive years.
12. Copper wire (tinned) is used as the ‘fuse wire’ to protect electrical circuits.
With d mm as the diameter of the wire used, the fusing current Ifis 80 × d1.5 amperes. Adapt the program in Example 3.10 to get the fusing current for a given d. For the set of values of d – {0.4, 0.6, 0.8, 1.0, 1.2} get the fusing currents.
13. Coffee Strength Equalization: Amla has three identical tumblers—A, B, and C.
Each is 80 % full. A has coffee decoction and B and C have milk. She has to prepare three tumblers of coffee of equal amount and equal strength (accurate to 1%) without the aid of any other vessel. From A she pours coffee into B and C andfills them; after this she goes through a similar cyclic pouring sequence—B to C, C to A, A to B and so on. How many times does she have to do this to get the required set? Solve this through a Python program.
14. Recurring Deposits and Equated Monthly Installment repayment of loan amount: a fixed amount of Rs 100/- is deposited every month in a recurring
38 3 Simple Programs
deposit scheme of a bank. The annual interest rate is r %. Write programs to do the following:
Compounding is done monthly; calculate the equivalent monthly simple interest rate.
With interest compounded every month calculate the maturity amount after y years.
With interest compounded annually calculate the maturity value of the amount.
Note that the problem of taking a loan and returning it as EMIs is the same as the recurring deposit scheme run in the reverse direction.
References
Guttag JV (2013) Introduction to computation and programming using Python. MIT Press, Massachusetts
Kreyszig E (2006) Advanced engineering mathematics, 9th edn. Wiley, New Jeresy
van Rossum G, Drake FL Jr (2014) The Python library reference. Python software foundation