Производная, код приближенного вычисления - C#
Формулировка задачи:
Доброго времени суток.
Столкнулся с проблемой поиска производной.
Программа должна находить корень по методу хорд.
Во время проверки условия неподвижности границы нужно искать двойную производную(численно).
У меня есть метод
А проверка выглядит так (в качестве C передается "край" диапазона)
f(c)*f''(c)>0.
Есть ли библиотека, или алгоритм готовый для такой цели?
Что бы выглядело примерно так
public double get_y(double x)
{
double y;
//Сюда уравнение, сам метод возвращает y.
y = Math.Pow(x, 4) + 4*Math.Pow(x, 3) - 8*Math.Pow(x, 2) - 17;
return y;
}if (get_y(c)*Оператор(get_y(с))>0)
{
.....
}Решение задачи: «Производная, код приближенного вычисления»
textual
Листинг программы
namespace Derivatives
{
class Program
{
public delegate double Function(double x);
#region Forward Derivatives
public static double DerivativeForward1(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (-3 * f(x) + 4 * f(x + h) - f(x + 2 * h)) / 2 / h;
}
public static double DerivativeForward1(double[] y, int i, double h)
{
if (y == null || y.Length < 3 || i < 0 || i > y.Length - 3 || h == 0)
return double.NaN;
return (-3 * y[i] + 4 * y[i + 1] - y[i + 2]) / 2 / h;
}
public static double DerivativeForward2(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (2 * f(x) - 5 * f(x + h) + 4 * f(x + 2 * h) - f(x + 3 * h)) / h / h;
}
public static double DerivativeForward2(double[] y, int i, double h)
{
if (y == null || y.Length < 4 || i < 0 || i > y.Length - 4 || h == 0)
return double.NaN;
return (2 * y[i] - 5 * y[i + 1] + 4 * y[i + 2] - y[i + 3]) / h / h;
}
public static double DerivativeForward3(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (-5 * f(x) + 18 * f(x + h) - 24 * f(x + 2 * h) + 14 * f(x + 3 * h) - 3 * f(x + 4 * h)) / 2 / h / h / h;
}
public static double DerivativeForward3(double[] y, int i, double h)
{
if (y == null || y.Length < 5 || i < 0 || i > y.Length - 5 || h == 0)
return double.NaN;
return (-5 * y[i] + 18 * y[i + 1] - 24 * y[i + 2] + 14 * y[i + 3] -
3 * y[i + 4]) / 2 / h / h / h;
}
public static double DerivativeForward4(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (3 * f(x) - 14 * f(x + h) + 26 * f(x + 2 * h) - 24 * f(x + 3 * h) + 11 * f(x + 4 * h) - 2 * f(x + 5 * h)) / h / h / h / h;
}
public static double DerivativeForward4(double[] y, int i, double h)
{
if (y == null || y.Length < 6 || i < 0 || i > y.Length - 6 || h == 0)
return double.NaN;
return (3 * y[i] - 14 * y[i + 1] + 26 * y[i + 2] - 24 * y[i + 3] +
11 * y[i + 4] - 2 * y[i + 5]) / h / h / h / h;
}
#endregion
#region Backward Derivatives
public static double DerivativeBackward1(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (3 * f(x) - 4 * f(x - h) + f(x - 2 * h)) / 2 / h;
}
public static double DerivativeBackward1(double[] y, int i, double h)
{
if (y == null || y.Length < 3 || i < 0 || i < 3 || h == 0)
return double.NaN;
return (3 * y[i] - 4 * y[i - 1] + y[i - 2]) / 2 / h;
}
public static double DerivativeBackward2(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (2 * f(x) - 5 * f(x - h) + 4 * f(x - 2 * h) - f(x - 3 * h)) / h / h;
}
public static double DerivativeBackward2(double[] y, int i, double h)
{
if (y == null || y.Length < 4 || i < 0 || i < 4 || h == 0)
return double.NaN;
return (2 * y[i] - 5 * y[i - 1] + 4 * y[i - 2] - y[i - 3]) / h / h;
}
public static double DerivativeBackward3(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (5 * f(x) - 18 * f(x - h) + 24 * f(x - 2 * h) - 14 * f(x - 3 * h) + 3 * f(x - 4 * h)) / 2 / h / h / h;
}
public static double DerivativeBackward3(double[] y, int i, double h)
{
if (y == null || y.Length < 5 || i < 0 || i < 5 || h == 0)
return double.NaN;
return (5 * y[i] - 18 * y[i - 1] + 24 * y[i - 2] - 14 * y[i - 3] +
3 * y[i - 4]) / 2 / h / h / h;
}
public static double DerivativeBackward4(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (3 * f(x) - 14 * f(x - h) + 26 * f(x - 2 * h) - 24 * f(x - 3 * h) + 11 * f(x - 4 * h) - 2 * f(x - 5 * h)) / h / h / h / h;
}
public static double DerivativeBackward4(double[] y, int i, double h)
{
if (y == null || y.Length < 6 || i < 0 || i < 6 || h == 0)
return double.NaN;
return (3 * y[i] - 14 * y[i - 1] + 26 * y[i - 2] - 24 * y[i - 3] +
11 * y[i - 4] - 2 * y[i - 5]) / h / h / h / h;
}
#endregion
#region Central Derivatives
public static double DerivativeCentral1(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (f(x + h) - f(x - h)) / 2 / h;
}
public static double DerivativeCentral1(double[] y, int i, double h)
{
if (y == null || y.Length < 3 || i < 1 || i > y.Length - 2 || h == 0)
return double.NaN;
return (y[i + 1] - y[i - 1]) / 2 / h;
}
public static double DerivativeCentral2(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (f(x - h) - 2 * f(x) + f(x + h)) / h / h;
}
public static double DerivativeCentral2(double[] y, int i, double h)
{
if (y == null || y.Length < 3 || i < 1 || i > y.Length - 2 || h == 0)
return double.NaN;
return (y[i - 1] - 2 * y[i] + y[i + 1]) / h / h;
}
public static double DerivativeCentral3(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (-f(x - 2 * h) + 2 * f(x - h) - 2 * f(x + h) + f(x + 2 * h)) / 2 / h / h / h;
}
public static double DerivativeCentral3(double[] y, int i, double h)
{
if (y == null || y.Length < 5 || i < 2 || i > y.Length - 3 || h == 0)
return double.NaN;
return (-y[i - 2] + 2 * y[i - 1] - 2 * y[i + 1] + y[i + 2]) / 2 / h / h / h;
}
public static double DerivativeCentral4(Function f, double x, double h)
{
h = (h == 0) ? 0.01 : h;
return (f(x - 2 * h) - 4 * f(x - h) + 6 * f(x) - 4 * f(x + h) + f(x + 2 * h)) / h / h / h / h;
}
public static double DerivativeCentral4(double[] y, int i, double h)
{
if (y == null || y.Length < 5 || i < 2 || i > y.Length - 3 || h == 0)
return double.NaN;
return (y[i - 2] - 4 * y[i - 1] + 6 * y[i] -
4 * y[i + 1] + y[i + 2]) / h / h / h / h;
}
#endregion
#region Test Functions
//Test function: f(x) = cos(x)
static double f1(double x)
{
return Math.Cos(x);
}
//Test function: f(x) = x^3 + e^x
static double f2(double x)
{
return x * x * x + Math.Exp(x);
}
static void TestForwardDifferenceMethod()
{
double h = 0.1;
// Calculate derivatives using f(x) = cos(x) at x=0.3:
Console.WriteLine("Using the FORWARD difference method\n");
double dy = DerivativeForward1(f1, 0.3, h);
Console.WriteLine(" f'(x) = " + dy.ToString());
dy = DerivativeForward2(f1, 0.3, h);
Console.WriteLine(" f''(x) = " + dy.ToString());
dy = DerivativeForward3(f1, 0.3, h);
Console.WriteLine(" f'''(x) = " + dy.ToString());
dy = DerivativeForward4(f1, 0.3, h);
Console.WriteLine(" f''''(x) = " + dy.ToString());
// Calculate derivatives using just array values at x=0.3 or i=3
Console.WriteLine("\nDerivatives using just array values:\n");
double[] y=new double[10];
for (int i = 0; i < 10; i++)
y[i] = f1(i * h);
dy = DerivativeForward1(y, 3, h);
Console.WriteLine(" y' = " + dy.ToString());
dy = DerivativeForward2(y, 3, h);
Console.WriteLine(" y'' = " + dy.ToString());
dy = DerivativeForward3(y, 3, h);
Console.WriteLine(" y''' = " + dy.ToString());
dy = DerivativeForward4(y, 3, h);
Console.WriteLine(" y'''' = " + dy.ToString());
Console.WriteLine("------------------------------------");
}
static void TestBackwardDifferenceMethod()
{
double h = 0.1;
// Calculate derivatives using f(x) = cos(x) at x=0.7:
Console.WriteLine("\nUsing the BACKWARD difference method\n");
double dy = DerivativeBackward1(f1, 0.7, h);
Console.WriteLine(" f'(x) = " + dy.ToString());
dy = DerivativeBackward2(f1, 0.7, h);
Console.WriteLine(" f''(x) = " + dy.ToString());
dy = DerivativeBackward3(f1, 0.7, h);
Console.WriteLine(" f'''(x) = " + dy.ToString());
dy = DerivativeBackward4(f1, 0.7, h);
Console.WriteLine(" f''''(x) = " + dy.ToString());
// Calculate derivatives for array values at x=0.7 or i=7:
Console.WriteLine("\nDerivatives for array values:\n");
double[] y = new double[10];
for (int i = 0; i < 10; i++)
y[i] = f1(i * h);
dy = DerivativeBackward1(y, 7, h);
Console.WriteLine(" y' = " + dy.ToString());
dy = DerivativeBackward2(y, 7, h);
Console.WriteLine(" y'' = " + dy.ToString());
dy = DerivativeBackward3(y, 7, h);
Console.WriteLine(" y''' = " + dy.ToString());
dy = DerivativeBackward4(y, 7, h);
Console.WriteLine(" y'''' = " + dy.ToString());
Console.WriteLine("---------------------------------------");
}
static void TestCentralDifferenceMethod()
{
double h = 0.1;
// Calculate derivatives using f(x) = cos(x) at x=0.5:
Console.WriteLine("\nUsing the CENTRAL difference method\n");
double dy = DerivativeCentral1(f1, 0.5, h);
Console.WriteLine(" f'(x) = " + dy.ToString());
dy = DerivativeCentral2(f1, 0.5, h);
Console.WriteLine(" f''(x) = " + dy.ToString());
dy = DerivativeCentral3(f1, 0.5, h);
Console.WriteLine(" f'''(x) = " + dy.ToString());
dy = DerivativeCentral4(f1, 0.5, h);
Console.WriteLine(" f''''(x) = " + dy.ToString());
// Calculate derivatives for array values at x=0.5 or i=5
Console.WriteLine("\nDerivatives for array values:\n");
double[] y = new double[10];
for (int i = 0; i < 10; i++)
y[i] = f1(i * h);
dy = DerivativeCentral1(y, 5, h);
Console.WriteLine(" y' = " + dy.ToString());
dy = DerivativeCentral2(y, 5, h);
Console.WriteLine(" y'' = " + dy.ToString());
dy = DerivativeCentral3(y, 5, h);
Console.WriteLine(" y''' = " + dy.ToString());
dy = DerivativeCentral4(y, 5, h);
Console.WriteLine(" y'''' = " + dy.ToString());
Console.WriteLine("---------------------------------------");
}
#endregion
static void Main(string[] args)
{
TestForwardDifferenceMethod();
TestBackwardDifferenceMethod();
TestCentralDifferenceMethod();
Console.ReadLine();
}
}
}