#13 (03/20/2024)

Roots of f(x) = 0

  1. Algebraic equations (Example: x5 + 3 x2 − 2 x = 0)
  2. Bisection method (slow, steady)
  3. Newton-Raphson method (fast, risk)

  1. Algebraic equations
    According to the Galois theorem, it is not possible to solve general algebraic equations of the fifth order and beyond in closed form.
    1. Quadratic equations
      a x2 + b x + c = 0,     x =
      b ±


      b2−4ac

      2a
      .
      (1)
      Example:
      x2 + 200000 x − 3 = 0.
      (2)
      The exact solutions are
      x1 = −200000,     x2 = 0.000015,
      (3)
      #include <stdio.h>
      #include <math.h>
      int main()
      {
      float a, b, c, disc,x1, x2;
      a=1.0;b=200000;c=-3;
      disc=b*b-4*a*c;
      x1=(-b-sqrt(disc))/(2*a);
      x2=(-b+sqrt(disc))/(2*a);
      printf("x1 = %f, x2 = %f\n",x1,x2); 
      return 0;
      } 
      
      What went wrong ??
      From eq.(1), one obtains
      D
      =
      200002 − 4×1.0 ×(−3)
      (4)
      =
      40000000012,
      (5)
      D
      =
      200000.00003
      (6)
      On the other hand,
      b = 200000.0
      (7)
      Subtraction of two numbers with similar magnitude may result in cancellation error.
      Solution 1 Change float to double
      Solution 2 Noting that
      a x2 + b x +c
      =
      a(xx1) (xx2)
      (8)
      =
      a (x2 − (x1+x2) x + x1 x2)
      (9)
      =
      a x2a (x1+x2) x+ a x1 x2,
      (10)
      so

      x1 x2 = c

      a
      ,
      (11)
      hence
      x2 = c

      x1 a
      = −3

      −200000
      = 0.000015.
      (12)
      Solution 3 Rationalization:

      x2
      =
      b + √D

      2a
      (13)
      =
      (−b−√D)(−b+√D)

      2a (−b − √D)
      (14)
      =
      b2D

      2a (−b − √D)
      ,
      (15)
      so
      x2 = −2000002 − 40000000012

      2 (−200000 − 200000)
      = 0.000015.
      (16)
    2. Cubic equations
      x3 + a x2 + b x+ c = 0.
      (17)
      (Try MathCheat.)
    3. Quartic equations
      x4 + a x3 + b x2+ c x + d = 0.
      (18)
      (Try MathCheat.)
  2. Bisection method
    The mean value theorem:
    If f(x) is continuous over x1xx2 and f′(x) exists over x1 < x < x2 and f(x1) f(x2) < 0, there is at least one point x between x1 and x2 such that f(x)=0.
    bisection1.gif
    1. Choose x1 and x2 such that f(x1) f(x2) < 0.
    2. Set x3 ← (x1+x2)/2.
    3. If f(x1) f(x3) < 0, then, set x2x3.
    4. Else set x1x3.
    5. Until |x1x2| < ϵ or f(x3) = 0, repeat b-d.
    bisection2.gif
    /* Compute the square root of 2 */
    #include <stdio.h>
    #include <math.h>
    #define EPS 1.0e-10
    #define N 100
    
    double f(double x)
    {
    return pow(x,2)-2;
    }
    
    /* start of main */
    int main()
    {
    double x1, x2, x3;
    int count;
    
    printf("Enter xleft and xright separated by space =");
    scanf("%f %f", &x1, &x2);
    
    /* sanity check */
    if (f(x1)*f(x2)>0) {printf("Invalid x1 and x2 !\n"); return 0;}
    
    /* bisection start */
    for (count=0;count< N; count++)
     {
     x3= (x1+x2)/2.0;
     if (f(x1)*f(x3)<0 ) x2=x3; else x1=x3;
     if ( f(x3)==0.0 || fabs(x1-x2)< EPS ) break;
    }
    
    printf("iteration = %d\n", count);
    printf("x= %f\n", x1);
    return 0;
    }
    
    Notes:
    1. fabs is a function to return the absolute value of the argument in math.h (list of functions)
    2. Try plotting a graph by gnuplot first.
    Example: By solving ex=2, obtain approximation of ln 2.
  3. Newton-Raphson Method
    newton1.gif
    The equation of a straight line that passes (a,b) with a slope of m is
    yb = m (xa),
    newton2.gif
    so the tangent line that passes (x1, f(x1)) with the slope of f ′(x1) is

    yf(x1) = f ′(x1) (xx1).
    newton3.gif

    0 − f(x1) = f ′(x1) (xx1),

    x = x1 f(x1)

    f ′(x1)
    ,

    x2 = x1 f(x1)

    f ′(x1)
    .

    x3 = x2 f(x2)

    f ′(x2)
    ,
    General forms:

    xn+1 = xn f(xn)

    f ′(xn)
    .
    Example: √2
    By solving f(x) ≡ x2 − 2 = 0 one can obtain a numerical value of √2.

    f(x)
    =
    x2 −2,
    f ′(x)
    =
    2 x.
    (19)
    Start with x1=2.0 (initial guess), then,
    x1
    =
    2
    (20)
    x2
    =
    2− f(2)

    f ′(2)
    = 2 − 2

    4
    = 1.5
    (21)
    x3
    =
    1.5 − f(1.5)

    f ′(1.5)
    = 1.5 − 0.25

    3
    = 1.41667
    (22)
    x4
    =
    1.4167− f(1.4167)

    f ′(1.4167)
    = … = 1.4142.
    (23)
    The convergence is attained after only 4 iterations.
    Algorithm:
    1. Pick an initial guess, x1.
    2. Make sure f ′(x1) ≠ 0.
    3. Repeat
      1. x2x1f(x1)/f ′(x1)
      2. x1x2
    4. Until |x1x2| ≤ ϵ.
    The Newton-Raphson method fails when f ′(xn) is zero.
    
    
    #include <stdio.h>
    #include <math.h>
    #define EPS 1.0e-10
    
    double f(double x)
    {
    	return x*x-2;
    }
    
    double fp(double x)
    {
    	return 2*x;
    }
    
    double newton(double x)
    {
    	return x - f(x)/fp(x);
    }
    
    int main()
    {
    	double x1, x2;
    	int i;
    
    	printf("Enter initial guess  =");
    	scanf("%f", &x1);
    
    	if (fp(x1)==0.0) {
    		printf("No convergence.\n");
    		return 0;
    	}
    
    	for (i=0;i<100;i++)
    	{
    		x2=newton(x1);
    		if (fabs(x1-x2)< EPS) break;
    		x1=x2;
    	}
    
    	printf("iteration = %d\n", i);
    	printf("x= %f\n", x1);
    	return 0;
    }
    
    

    Some interesting examples

    The following examples are useful in emergency when you do not have an access to a computer.
    1. Square root of a ( = √a)
      Let f(x) = x2a, the Newton-Raphson method yields

      xn+1
      =
      xn xn2a

      2 xn
      (24)
      =
      1

      2

      xn + a

      xn

      .
      (25)
      Example (√3 = 1.732 …)
      x1=1,     x2 = 1

      2
      (1 + 3

      1
      ) = 2,    x3 = 1

      2
      (2 + 3

      2
      ) = 1.75,    x4 = 1

      2
      (1.75 + 3

      1.75
      ) = 1.732.
    2. Inverse of a ( = 1/a)
      Let f(x) = 1/xa, the Newton-Raphson method yields
      xn+1
      =
      xn
      1

      xn
      a

      −1

      xn2
      (26)
      =
      xn (2 − a xn).
      (27)
      In case you forgot how to do divisions, you can use this formula.
      Example (1/6 = 0.16667…)

      x1 = 0.2,     x2 = 0.2 (2 − 6×0.2)=0.16,    x3 = 0.16 (2 − 6×0.16) = 0.1664,    x4 = 0.1664 (2 − 6×0.1664) = 0.166666.
    3. 1/√a
      Let f(x) = 1/x2a,

      xn+1
      =
      xn 1/xn2a

      − 2/xn3
      (28)
      =
      xn (3 − a xn2)/2.
      (29)

Summary

Solving simultaneous equations


A x = c,
(30)
or







a11
a12
a1n
a21
a22
a2n
:
:
:
:
an1
an2
ann












x1
x2
:
xn






=





c1
c2
:
cn






,
(31)
or









a11 x1 + a12 x2 + a13 x3 + …+ a1nxn = c1
a21 x1 + a22 x2 + a23 x3 + …+ a2nxn = c2
a31 x1 + a32 x2 + a33 x3 + …+ a3nxn = c3
……
an1 x1 + an2 x2 + an3 x3 + …+ annxn = cn
(32)
For many problems in engineering/science, the size of the matrix A can easily go up to n=1,000,00.

Determinant

  1. 2 ×2 matrices



    a11
    a12
    a21
    a22.



    a11 a22a12 a21
    (33)
  2. 3 ×3 matrices




    a11
    a12
    a13
    a21
    a22
    a23
    a31
    a32
    a33




    a11 a22 a33 + a12 a23 a31+ a21 a32 a13a13 a22a31a12 a21 a33a23 a32 a11
    (34)
  3. The determinant of n ×n (n > 3) matrices can be expressed similar to the above. It consists of n! terms each of which is a product of n variables.

Some properties of determinants

  1. | A B | = | A | | B |
  2. | I | = 1 where I is the identity matrix.
  3. | A |=0 ⇒ A is singular.

Determinant/Cramer's rule

Solving
a11 x1 + a12 x2
=
c1
a21 x1 + a22 x2
=
c2
(35)
yields

x1
=
c1 a22c2 a12

a11 a22a12 a21
=



c1
a12
c2
a22







a11
a12
a21
a22



(36)
x2
=
c2 a11c1 a21

a11 a22a12 a21
=



a11
c1
a21
c2







a11
a12
a21
a22



(37)
Similarly, for three simultaneous equations,

a11 x1 + a12 x2 + a13 x3
=
c1
a21 x1 + a22 x2 + a23 x3
=
c2
a31 x1 + a32 x2 + a33 x3
=
c3
(38)
the solution is expressed as

x1
=




c1
a12
a13
c2
a22
a23
c3
a32
a33









a11
a12
a13
a21
a22
a23
a31
a32
a33




,
(39)
x2
=




a11
c1
a13
a21
c2
a23
a31
c3
a33









a11
a12
a13
a21
a22
a23
a31
a32
a33




,
(40)
x3
=




a11
a12
c1
a21
a22
c2
a31
a32
c3









a11
a12
a13
a21
a22
a23
a31
a32
a33




.
(41)
The above formulas are called Cramer's rule and in general can be extended to higher order matrices. However, it's not practical to use Cramer's rule for a set of more than 4 simultaneous equations. The number of multiplications required for Cramer's rule for n simultaneous equations is n! (n−1) (n+1). For n=10, this amounts to 3,628,800.
Approximate computational time for n simultaneous equations with a 100 MFLOPS computer (an old PC) using Cramer's rule is estimated as shown in Table .1
Table 1: Time required for Cramer's rule
n 10 12 14 16 18 20
Time 0.4 sec. 1 min. 3.6 hrs. 41 days 38 years 16,000 years

Gauss-Jordan elimination method

The linearity principle:

a11 x1 + a12x2 + …+a1nxn
=
c1
a21 x1 + a22x2 + …+a2nxn
=
c2,
(42)

1 a11 + λ2 a12)x1+(λ1 a21 + λ2 a22)x2+…+(λ1 a1n + λ2 a2n)xn = λ1 c1 + λ2 c2.
(43)
Example

2x+3y+4z = 6
3x+5y+2z = 5
4x+3y+30z=32.




(44)


1x+0y+0z = ?
0x+1y+0z = ?
0x+0y+1z = ?.




(45)
Ref. line number x y z = Comment
(1) 2 3 4 6
(2) 3 5 2 5
(3) 4 3 30 32
(4) 1 1.5 2 3 (1)÷2
(5) 3 5 2 5
(6) 4 3 30 32
(7) 1 1.5 2 3
(8) 0 0.5 -4 -4 (5)−(4)×3
(9) 0 -3 22 20 (6)−(4)×4
(10) 1 1.5 2 3
(11) 0 1 -8 -8 (8)÷0.5
(12) 0 -3 22 20
(13) 1 0 14 15 (10)−(11)×1.5
(14) 0 1 -8 -8
(15) 0 0 -2 -4 (12)−(11)×(−3)
(16) 1 0 14 15
(17) 0 1 -8 -8
(18) 0 0 1 2 (15)÷(−2)
(19) 1 0 0 -13 (16)−(18)×14
(20) 0 1 0 8 (17)− (18)×(−8)
(21) 0 0 1 2
Finally we obtain
x = −13,     y=8,     z=2.
The number of multiplications required for the Gauss-Jordan elimination method is about n3. For n=10, this amounts to 1,000. Compare this number with the one required for Cramer's rule.

Inverse matrix by the Gauss-Jordan elimination method (optional)

Apply the Gauss-Jordan elimination method for
( A | I)
(46)
i.e.





2
3
4
1
0
0
3
5
2
0
1
0
4
3
32
0
0
1








1
2/3
2
1/2
0
0
0
1/2
−4
−3/2
1
0
0
−3
22
−2
0
1








1
0
14
5
−3
0
0
1
−8
−3
2
0
0
0
−2
−11
6
1








1
0
0
−72
39
7
0
1
0
41
−22
−4
0
0
1
11/2
−3
−1/2




(47)
We thus obtain
A−1 =



−72
39
7
41
−22
−4
11/2
−3
−1/2




(48)

Implementation

#include <stdio.h>
#define N 3
int main()
{
 double a[N][N+1]={{2, 3, 4, 6},{3, 5, 2, 5},{4, 3, 30, 32}};
  double pivot,d;
  int i,j,k;

for(k=0; k<N; k++)
{
 pivot=a[k][k];

 for(j=k; j<N+1; j++) a[k][j]=a[k][j]/pivot;
 for(i=0; i<N;  i++)
  {
    if(i != k)
     {
       d=a[i][k]; 
        for(j=k; j<N+1; j++) a[i][j]=a[i][j]-d*a[k][j];
     }
   }
}

for(i=0; i<N; i++) printf("x[%d]=%f\n", i+1, a[i][N]);
return 0;
}

LU decomposition (optional)

Any matrix, A, can be uniquely factorized as

A = L U,
(49)
where

L =






1
0
0
0
l21
1
0
0
l31
l32
1
0
:
:
:
···
:
ln1
ln2
ln3
1







,   U =






u11
u12
u13
u1n
0
u22
u23
u2n
0
0
u33
u3n
:
:
:
···
:
0
0
0
unn







.
(50)
The matrix, L, is a lower triangular matrix and the matrix, U, is an upper triangular matrix. Note that the diagonal elements of L are set to be 1. This decomposition is called LU decomposition (or LU factorization) and provides an effective way of solving simultaneous equations which is more efficient than the Gauss-Jordan elimination method.
The decomposition above is unique as it is possible to find L and U directly as







1
0
0
0
l21
1
0
0
l31
l32
1
0
l41
l42
l43
1












u11
u12
u13
u14
0
u22
u23
u24
0
0
u33
u34
0
0
0
u44






=





a11
a12
a13
a14
a21
a22
a23
a24
a31
a32
a33
a34
a41
a42
a43
a44






.
(51)
Writing each element explicitly gives







u11 = a11,
u12=a12,
u13=a13,
u14=a14
l21 u11 = a21,
l21 u12+u22 = a22,
l21 u13+u23 = a23,
l21 u14+u24 = a24
l31u11 = a31,
l31u12+l32u22 = a32,
l31u13+l32u23+u33 = a33,
l31u14+l32u24+u34 = a34
l41u11 = a41,
l41u12+l42u22 = a42,
l41u13+l42u23+l43u33 = a43,
l41u14+l42u24+l43u34+u44 = a44,
(52)
from which one can solve the unknowns, lij and uij, as











u11=a11,
u12=a12,
u13=a13,
u14=a14
l21= a21

u11
,
u22 = a22l21u12,
u23=a23l21 u13,
u24=a24l21u14
l31= a31

u11
,
l32= a32l31u12

u22
,
u33=a33l31 u13l32 u23,
u34=a34l31 u14l32 u24
l41= a41

u11
,
l42 = a42l41u12

u22
,
l43= a43l41u13l42u23

u33
,
u44=a44l41u14l42u24l43u34.
(53)
Note that the immediate results for uij and lij must be used to solve for the next result.
To solve
A x = L U x = c,
(54)
  1. Solve L y = c first.
  2. Then, solve U x = y.
Finding L and U from A requires less effort than finding A−1 and can accomplish the same goal as finding A−1.







1
0
0
0
l21
1
0
0
l31
l32
1
0
l41
l42
l43
1












y1
y2
y3
y4






=





c1
c2
c3
c4






(55)
This can be solved easily as







y1 = c1
l21 y1 + y2 = c2
l31 y1 + l32y2 + y3 = c3
l41 y1 +l42 y2 + l43y3 + y4 = c4
(56)
from which one obtains







y1 = c1
y2 = c2l21 y1
y3 = c3l31 y1l32y2
y4 = c4l41 y1l42 y2l43y3
(57)
For U x=y,







u11
u12
u13
u14
0
u22
u23
u24
0
0
u33
u34
0
0
0
u44












x1
x2
x3
x4






=





y1
y2
y3
y4






(58)
First







u11 x1 + u12 x2 + u13 x3 + u14 x4 = y1
u22 x2+u23x3 + u24x4 = y2
u33 x3 + u34x4 = y3
u44 x4=y4
(59)
from which one obtains













x4 = y4

u44
x3 = y3u34x4

u33
x2 = y2u23x3u24x4

u22
x1 = y1u11 x1u12 x2u13 x3

u11
(60)
This procedure is called backward substitution.
It can be shown that the number of operations (multiplications, divisions) to decompose A into A = LU is about n3/3 and to obtain x from Ly=c and Ux=y, n2 is required so the total number of operations is about n3/3 which is 1/3 of the number required for the Gauss-Jordan elimination method.

Notes

  1. If A is a symmetric matrix (aij=aji), LU-decomposition is called the Cholesky decomposition. The number of operations required for the Cholesky decomposition is n3/6.
  2. If A is a sparse matrix, so are L and U.
  3. If A is a triangular diagonal matrix (typical of the finite element method), so are L and U.

Gauss-Seidel method (Important)

If the diagonal elements of the matrix, A, are generally larger than non-diagonal elements, the linear equation, A x = c, can be solved by an iterative method called the Gauss-Seidel method.
Example:





7x+y+2z
=
10
x+8y+3z
=
8
2x+3y+9z
=
6.
(61)





x
=
(10−y−2z)/7
y
=
(8−x−3z)/8
z
=
(6−2x−3y)/9.
(62)





xn+1
=
(10−yn−2zn)/7
yn+1
=
(8−xn−3zn)/8
zn+1
=
(6−2xn−3yn)/9,
(63)
with x0 = y0 = z0 = 0 as the initial approximation. This scheme is also called the Jacobi method. A slightly better iteration scheme is to use the most immediate values for the next approximation, i.e.





xn+1
=
(10−yn−2zn)/7
yn+1
=
(8−xn+1−3zn)/8
zn+1
=
(6−2xn+1−3yn+1)/9,
(64)
This scheme is called the Gauss-Seidel iterative method. It is easy to implement this method:
#include <stdio.h>
int main()
{
double x, y, z;
int i,n;

x=y=z=0.0;

printf("Enter # of iteration = ");
scanf("%d", &n);

for (i=0;i<n;i++)
{
x = (10-y-2*z)/7;
y = (8-x-3*z)/8.0;
z = (6-2*x-3*y)/9.0;
}

printf("x = %f, y= %f, z=%f\n", x,y,z);
return 0;
}


Footnotes:

1Dahmen and Reusken, Numerik für Ingenieure und Naturwissenschaftler, Springer, 2006.


File translated from TEX by TTH, version 4.03.
On 19 Mar 2024, 13:08.