立方根の計算
Posted feedbacks - C#
ニュートン法にしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | public static double CubeRoot(double x)
{
double a0 = (double)(-x);
double[] a = { a0, 0.0, 0.0, 1.0 };
return SolveAlgebraicEquationByNewtonMethod(a, 1e-12);
}
delegate double MathFunc(double x);
static double SolveAlgebraicEquationByNewtonMethod(double[] a, double delta)
{
MathFunc f = CreateFunc(a);
MathFunc fPrime = CreateFunc(Derivative(a));
double x = 1.0;
while (NearlyEquals(fPrime(x), 0.0, double.Epsilon))
x += 1.0;
double betterX = 0;
while (true)
{
betterX = Newton(f, fPrime, x);
if (NearlyEquals(x, betterX, delta))
break;
x = betterX;
}
return betterX;
}
static MathFunc CreateFunc(double[] a)
{
return delegate(double x)
{
double fx = 0.0;
for (int i = 0; i < a.Length; i++)
{
double d = a[i];
if (NearlyEquals(d, 0.0, double.Epsilon))
continue;
for (int j = 0; j < i; j++)
d *= x;
fx += d;
}
return fx;
};
}
static double[] Derivative(double[] a)
{
double[] aPrime = new double[a.Length - 1];
for (int i = 1; i < a.Length; i++)
{
aPrime[i - 1] = a[i] * (double)i;
}
return aPrime;
}
static double Newton(MathFunc f, MathFunc fPrime, double x)
{
return x - (f(x) / fPrime(x));
}
static bool NearlyEquals(double d1, double d2, double delta)
{
return (((d1 - d2) <= delta) && ((d2 - d1) <= delta));
}
|


にしお
#3411()
Rating1/1=1.00
ただし、このお題の趣旨は実数区間での探索なので、 立方根関数があっても使ってはいけません。 指数関数と対数関数も禁止します。
Pythonで表現した入出力の例:
[ reply ]