Mathematics/Numerical Method
Solving Non-Linear Equations
Taesan Kim
2024. 9. 11. 22:45
Solving Non-Linear Equations
Intro
This posting will give you some methods to help you find a nonlinear equation's approximated value. Before organizing our purpose, let's see this example problem.
Example MATLAB function
%================================================
%Handong Global University
%------------------------------------------------
%Name: Taesan Kim
%ID: 22300203
%Create: 2024.09.05
%Modifire: 2024.09.05
%------------------------------------------------
%Plot of Trajectory Formula
%================================================
clc, clear all, close all;
t = 0:1e-3:45;
t0 = 3.0; %Find the most closest value with initial value 10.
sol = fzero(@fn,t0); %fzero find x which make @function = 0
axis equal;
plot(t, fn(t)); grid on
xlabel('x[-]'); ylabel('f(t)');
%Find theta which is solution of fnTrajectory = 0
disp(['Solution for t where fn = 0: ', num2str(sol), ' degrees']);
%Trajectory formula
function z=fn(t)
x=20; y=2; v=17; g=9.8;
z=x.*tand(t)-g.*x.*x./(2.*v.*v.*cosd(t).*cosd(t))-y;
end
Purpose
We want to derive a non-linear equation's solution not using fzero function. We will learn how to make fzero() to solve a non-linear equation with one variable, f(x) = 0. Then, we will expand the algorithm to solve a system of non-linear equations. This posting will organize 3 methods including the Bisection method, Newton-Raphson, and Secant's method.
Bisection method
Newton-Raphson method
Secant method
Header code
/*
================================================
Handong Global University
------------------------------------------------
Name: Taesan Kim
ID: 22300203
Create: 2024.07.19
Modifier: 2024.07.19
------------------------------------------------
비선형 근삿값 계산을 지원한다.
================================================
*/
#ifndef MYNP22300203_H
#define MYNP22300203_H
#include <stdio.h>
#include <math.h>
/**
* Name: Non-linear approximation method newtonRaphson
* Date: 2024/09/09
* Input:
* - func: non-linear function
* - dfunc: differential non-linear function
* - x0: initial value
* - tol: allowence tolerance
* Return: None(Print error)
**/
void newtonRaphson(double func(double x), double dfunc(double x), double x0, double tol);
/**
* Name: Non-linear approximation method secant
* Date: 2024/09/09
* Input:
* - func: non-linear function
* - x0, x1: initial value
* - tol: allowence tolerance
* Return: xk
**/
float secantfzero(double func(double x), double dfunc(double x), double x0, double x1, double tol);
/**
* Name: Non-linear approximation method biSection
* Date: 2024/09/09
* Input:
* - func: non-linear function
* - tol: allowence tolerance
* - a, b: 2D area [a, b]
* Return: None(Print error)
**/
void biSection(double func(double x), double tol, double a, double b);
#endif
Source code
#include "myNP.h"
void biSection(double func(double x), double tol, double a, double b)
{
printf("===================================================================\n");
printf(" Bi-Section Method Results\n");
printf("===================================================================\n");
printf("Bi-Section Method Result:\n");
int Nmax = 1000;
double ep = 10.0;
double xk = 0.0;
int i = 0;
if (func(a) * func(b) > 0)
printf("Solution dont exists in this area!");
else
while (Nmax > i && ep > tol)
{
xk = 0.5 * (a + b);
if (func(a) * func(xk) < 0)
{
b = xk;
}
else
{
a = xk;
}
i++;
ep = fabs(func(xk));
printf("Iteration: %2d Xn(k): %f Tolerance: %f\n", i, xk, ep);
}
if (i == Nmax) printf("Solution did not converge !!!");
printf("Final Solution: %f\n", xk);
}
void newtonRaphson(double func(double x), double dfunc(double x), double x0, double tol)
{
printf("===================================================================\n");
printf(" Newton-Raphson Method Results\n");
printf("===================================================================\n");
printf("Newton-Raphson Method Results:\n");
int Nmax = 10000;
double ep = 10.0;
double xk = x0;
double h = 0.0; int i = 0;
while (i<Nmax && ep> tol)
{
if (dfunc(xk) == 0) printf("Error!! dF=0 !!");
h = -func(xk) / dfunc(xk);
xk = xk + h;
i++;
ep = fabs(func(xk));
printf("Iteration: %2d Xn(k): %f Tolerance: %f\n", i, xk, ep);
}
if (i == Nmax) printf("Solution did not converge !!!");
printf("Final Solution: %f\n", xk);
}
float secantfzero(double func(double x), double dfunc(double x), double x0, double x1, double tol)
{
printf("===================================================================\n");
printf(" Secant Method Results\n");
printf("===================================================================\n");
printf("Secant Method Results:\n");
//initialize
double xk = x0; //최종 xk를 구해준다.
double temp = 0.0;
double ep = 10.0;
int Nmax = 1000; int i = 0;
while (ep > tol && i < Nmax)
{
if ((func(x1) - func(x0)) * func(x1) == 0)
{
printf("Error!! dF=0 !!");
break;
}
temp = xk;
xk = x1 - (x1 - x0) / (func(x1) - func(x0)) * func(x1);
x0 = x1;
x1 = temp;
i++;
ep = fabs(func(xk));
printf("Iteration: %2d Xn(k): %f Tolerance: %f\n", i, xk, ep);
}
return xk;
printf("Final Solution: %f\n", xk);
}
Main code
#include "../../include/myNP.h"
#define pi 3.141592653589793238462643383279
/**
* Name: example non-linear function
* Date: 2024/09/09
* Input: x
* Return: function output
**/
double func(double x)
{
//return 8 - 4.5 * (x - sin(x));
x = x * pi / 180; // deg2rad
return 20 * tanf(x) - 9.8 * 200 / (17*17 * cosf(x)*cosf(x))-2;
}
/**
* Name: example non-linear differential function
* Date: 2024/09/09
* Input: x
* Return: differential function output
**/
double dfunc(double x)
{
//return -4.5 * (1 - cos(x));
return 20 * (1/cosf(x)) * (1/cos(x)) - 9.8 * 400 * tanf(x) * (1/cosf(x)) * (1/cosf(x)) /289;
}
int main()
{
biSection(func, 1e-5, 20,30);
newtonRaphson(func, dfunc, 28, 1e-5);
printf("%f", secantfzero(func, dfunc, 29, 30, 1e-5));
}
*you should set your myNP.cpp, myNP.h file in the include folder.