Реализация производной в C/C++

Вот соглашение. Когда Вы звоните

TestClass tc = new TestClass();

эти new, команда выполняет четыре важных задачи:

  1. Выделяет память на "куче" для нового объекта.
  2. Посвященные поля класса к их значениям по умолчанию (численные данные к 0, булевская переменная к false, объекты к null).
  3. Вызовы конструктор (который может повторно инициировать поля или не может).
  4. Возвраты ссылка на новый объект.

, Таким образом, Ваши поля и 'b' и инициируются к null, и переинициированного в конструкторе. Этот процесс не важен для вызова метода, таким образом, локальная переменная 'c' никогда инициализирована.

HTH

пз: для серьезно страдающего бессонницей, читайте это .

21
задан Peter Mortensen 17 October 2017 в 19:08
поделиться

8 ответов

Я согласен с @erikkallen, что (f (x + h) - f (x - h)) / 2 * h является обычным подходом для численного приближения производных. Однако получить правильный размер шага h немного сложно.

Ошибка аппроксимации в ( f (x + h) - f (x - h)) / 2 * h уменьшается по мере того, как h становится меньше, что означает, что вы должны взять ч как можно меньше. Но по мере того как h становится меньше, ошибка вычитания с плавающей запятой увеличивается, поскольку числитель требует вычитания почти равных чисел. Если h слишком мало, вы можете сильно потерять точность при вычитании. Поэтому на практике вы должны выбрать не слишком маленькое значение h , которое минимизирует комбинацию ошибки аппроксимации и числовой ошибки.

Как правило, вы можете попробовать h = SQRT (DBL_EPSILON) , где DBL_EPSILON - наименьшее число двойной точности e такое, что 1 + e! = 1 в машинной точности. DBL_EPSILON составляет около 10 ^ -15 , поэтому вы можете использовать h = 10 ^ -7 или 10 ^ -8 .

Для получения дополнительной информации см. Эти примечания о выборе размера шага для дифференциальных уравнений.

60
ответ дан 29 November 2019 в 06:09
поделиться

Newton_Raphson предполагает, что у вас может быть две функции f (x) и ее производная f '(x). Если у вас нет производной, доступной как функция, и вам необходимо оценить производную от исходной функции, тогда вам следует использовать другой алгоритм поиска корня.

Поиск корня в Википедии дает несколько предложений, как и любой текст численного анализа.

10
ответ дан 29 November 2019 в 06:09
поделиться

alt text

alt text

1) Первый случай:

alt text

alt text - относительная ошибка округления, около 2 ^ {- 16} для double и 2 ^ {- 7} для float.

Мы можем вычислить общая ошибка:

alt text

Предположим, вы используете двойную операцию с плавающей запятой. Таким образом, оптимальное значение h составляет 2sqrt (DBL_EPSILON / f '' (x) ). Вы не знаете f '' (x) . Но вы должны оценить эту стоимость. Например, если f '' (x) примерно равно 1, то оптимальное значение h равно 2 ^ {- 7}, но если f '' (x) составляет примерно 10 ^ 6, тогда оптимальное значение h равно 2 ^ {- 10}! Но если f '' '(x) очень запаздывающее, то первый вариант более предпочтителен:

alt text

Обратите внимание, что в первом случае h пропорционально e, а во втором случае h пропорционально e ^ {1/3}. Для двойных операций с плавающей запятой e ^ {1/3} равно 2 ^ {- 5} или 2 ^ {- 6}. (Я полагаю, что f '' '(x) около 1).


Какой способ лучше? Неизвестно, если вы не знаете f '' (x) и f '' '(x) или не можете оценить эти значения. Считается, что второй вариант предпочтительнее. Но если вы знаете, что f '' '(x) очень большое значение, используйте сначала.

Какое оптимальное значение h? Предположим, что f' '(x) и f' '' (x) равны около 1. Также предположим, что мы используем двойные операции с плавающей запятой. Тогда в первом случае h примерно равно 2 ^ {- 8}, в первом случае h примерно равно 2 ^ {- 5}. Исправьте эти значения, если знаете f ''

9
ответ дан 29 November 2019 в 06:09
поделиться
fprime(x) = (f(x+dx) - f(x-dx)) / (2*dx)

для небольшого dx.

5
ответ дан 29 November 2019 в 06:09
поделиться

Что вы знаете о f (x)? Если у вас есть только f в виде черного ящика, единственное, что вы можете сделать, - это численно аппроксимировать производную. Но точность обычно не так хороша.

Вы можете сделать намного лучше, если прикоснетесь к коду, который вычисляет f. Попробуйте «автоматическое дифференцирование» . Для этого есть несколько хороших библиотек. Немного библиотечной магии вы можете легко преобразовать свою функцию во что-то, что вычисляет производную автоматически. Простой пример C ++ можно найти в исходном коде в этом немецком обсуждении.

5
ответ дан 29 November 2019 в 06:09
поделиться

В дополнение к ответу Джона Д. Кука выше важно не только учитывают точность с плавающей запятой, а также надежность функции f (x). Например, в финансах часто бывает, что f (x) фактически является моделированием Монте-Карло, а значение f (x) имеет некоторый шум. Использование очень маленького шага в этих случаях может сильно снизить точность производной.

3
ответ дан 29 November 2019 в 06:09
поделиться

Вы определенно хотите принять во внимание предложение Джона Кука о выборе h, но обычно вы не хотите использовать центрированную разницу для аппроксимации производной. Основная причина в том, что это требует дополнительной оценки функции, если вы используете прямую разницу, то есть

f'(x) = (f(x+h) - f(x))/h

Тогда вы получите значение f (x) бесплатно, потому что вам нужно вычислить его уже для метода Ньютона. Это не такая уж большая проблема, когда у вас есть скалярное уравнение, но если x - вектор, тогда f '(x) - это матрица (якобиан), и вам нужно будет выполнить n дополнительных вычислений функций, чтобы аппроксимировать ее. используя подход центрированной разности.

5
ответ дан 29 November 2019 в 06:09
поделиться

Обычно шум сигнала влияет на качество производной больше, чем что-либо еще. Если у вас есть шум в вашем f (x), Савтицкий-Голей - отличный алгоритм сглаживания, который часто используется для вычисления хороших производных. Вкратце, SG подбирает полином локально к вашим данным, затем этот полином можно использовать для вычисления производной.

Пол

1
ответ дан 29 November 2019 в 06:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: