要求得一條方程式 f(x) = 0 的根時,其實有很多種解法
但是當這條方程式為非線性時,就沒有辦法使用簡單的推導求得
這時候我們即可使用牛頓法來求解
牛頓法的詳細說明請參考維基百科,其中述及該方法需要使用一階微分迭代近似
在此我實作了 NewtonRaphson 這個虛擬類別,建構其處理流程
並在這個虛擬類別中實作了 Derivative 這個函式,以推估該方程式的一階微分,
其理論源自於微分使用極限值(limit)逼近
當要求一個方程式的根時,我們只要繼承這個類別並實作 F 這個函式即可計算出其解。
class Program
{
static void Main(string[] args)
{
NewtonRaphson n = new CosRoot();
NewtonRaphson s = new SquareRoot();
int counter;
double result = n.GetRoot(0.5, out counter);
Console.WriteLine("{0} its root is {1}. {2}", n.ToString(), result, counter);
result = s.GetRoot(1, out counter);
Console.WriteLine("{0} its root is {1}. {2}", s.ToString(), result, counter);
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
abstract class NewtonRaphson
{
private int iteratorCount;
public NewtonRaphson()
{
iteratorCount = 10000;
}
abstract protected double F(double x);
private double Derivative(double x){
double h = 0.0000001;
return (F(x + h) - F(x)) / h;
}
public double GetRoot(double initValue, out int counter)
{
double tmpValue = initValue;
counter = 0;
for (int i = 0; i < iteratorCount; i++)
{
initValue = initValue - F(initValue) / Derivative(initValue);
if (Math.Abs(initValue - tmpValue) <= 0.00000000001)
break;
tmpValue = initValue;
counter++;
}
return initValue;
}
}
class CosRoot : NewtonRaphson
{
protected override double F(double x)
{
return Math.Cos(x) - Math.Pow(x, 3);
}
public override string ToString()
{
return "Cos(x) - x^3";
}
}
class SquareRoot : NewtonRaphson
{
protected override double F(double x)
{
return x * x - 612;
}
public override string ToString()
{
return "x^2 - 612";
}
}
沒有留言:
張貼留言